chelper: fix for objc methods, protocols parsing and writting
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1288 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
e3d745b988
commit
dd80a33837
@ -226,9 +226,69 @@ type
|
|||||||
_Params : AnsiString;
|
_Params : AnsiString;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// parsing function
|
type
|
||||||
|
|
||||||
|
{ TSimpleType }
|
||||||
|
|
||||||
|
TSimpleType = class(TEntity)
|
||||||
|
public
|
||||||
|
Name : AnsiString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TExpression }
|
||||||
|
|
||||||
|
TExpPart = record
|
||||||
|
Token : AnsiString;
|
||||||
|
TokenType : TTokenType;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TExpression = class(TEntity)
|
||||||
|
function DoParse(AParser: TTextParser): Boolean; override;
|
||||||
|
public
|
||||||
|
Tokens : array of TExpPart;
|
||||||
|
Count : Integer;
|
||||||
|
procedure PushToken(const AToken: AnsiString; ATokenType: TTokenType);
|
||||||
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
nk_Ident = 0;
|
||||||
|
nk_Ref = 1;
|
||||||
|
nk_Array = 2;
|
||||||
|
nk_Func = 3;
|
||||||
|
|
||||||
|
type
|
||||||
|
TNameKind = Integer;
|
||||||
|
|
||||||
|
type
|
||||||
|
TNamePart = class;
|
||||||
|
|
||||||
|
TFuncParam = record
|
||||||
|
prmtype : TEntity;
|
||||||
|
name : TNamePart;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TNamePart }
|
||||||
|
|
||||||
|
TNamePart = class(TObject)
|
||||||
|
private
|
||||||
|
fChild : TNamePart;
|
||||||
|
fOwner : TNamePart;
|
||||||
|
public
|
||||||
|
Kind : TNameKind;
|
||||||
|
RefCount : Integer;
|
||||||
|
Id : AnsiString;
|
||||||
|
arrayexp : array of TExpression;
|
||||||
|
params : array of TFuncParam;
|
||||||
|
constructor Create(AKind: TNameKind);
|
||||||
|
procedure AddParam(prmtype: TEntity; prmname: TNamePart);
|
||||||
|
procedure AddArrayExpr(expr: TExpression);
|
||||||
|
property child: TNamePart read fchild write fChild; // int (*p)[10]; "[10]" is child of (*p)
|
||||||
|
property owner: TNamePart read fowner write fOwner;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
ParseNextEntity: function (AParser: TTextParser): TEntity = nil;
|
ParseNextEntity: function (AParser: TTextParser): TEntity = nil;
|
||||||
|
ParseNamePart : function (Parser: TTextParser): TNamePart = nil;
|
||||||
|
|
||||||
function ParseNextCEntity(AParser: TTextParser): TEntity;
|
function ParseNextCEntity(AParser: TTextParser): TEntity;
|
||||||
|
|
||||||
@ -254,64 +314,12 @@ function CreateCParser(const CHeaderText: AnsiString;
|
|||||||
type
|
type
|
||||||
TCustomEntityProc = function (Parent: TEntity; Parser: TTextParser): TEntity;
|
TCustomEntityProc = function (Parent: TEntity; Parser: TTextParser): TEntity;
|
||||||
|
|
||||||
type
|
|
||||||
|
|
||||||
{ TSimpleType }
|
|
||||||
|
|
||||||
TSimpleType = class(TEntity)
|
|
||||||
public
|
|
||||||
Name : AnsiString;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TExpression }
|
|
||||||
|
|
||||||
TExpPart = record
|
|
||||||
Token : AnsiString;
|
|
||||||
TokenType : TTokenType;
|
|
||||||
end;
|
|
||||||
TExpression = class(TEntity)
|
|
||||||
function DoParse(AParser: TTextParser): Boolean; override;
|
|
||||||
public
|
|
||||||
Tokens : array of TExpPart;
|
|
||||||
Count : Integer;
|
|
||||||
procedure PushToken(const AToken: AnsiString; ATokenType: TTokenType);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure ErrorExpect(Parser: TTextParser; const Expect: AnsiString);
|
procedure ErrorExpect(Parser: TTextParser; const Expect: AnsiString);
|
||||||
function ConsumeToken(Parser: TTextParser; const Token: AnsiString): Boolean;
|
function ConsumeToken(Parser: TTextParser; const Token: AnsiString): Boolean;
|
||||||
function ConsumeIdentifier(Parser: TTextParser; var Id: AnsiString): Boolean;
|
function ConsumeIdentifier(Parser: TTextParser; var Id: AnsiString): Boolean;
|
||||||
|
|
||||||
function ParseCType(Parser: TTextParser): TEntity;
|
function ParseCType(Parser: TTextParser): TEntity;
|
||||||
|
|
||||||
type
|
|
||||||
TNamePart = class;
|
|
||||||
|
|
||||||
TFuncParam = record
|
|
||||||
prmtype : TEntity;
|
|
||||||
name : TNamePart;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TNameKind = (nk_Ident, nk_Ref, nk_Array, nk_Func);
|
|
||||||
|
|
||||||
{ TNamePart }
|
|
||||||
|
|
||||||
TNamePart = class(TObject)
|
|
||||||
private
|
|
||||||
fChild : TNamePart;
|
|
||||||
fOwner : TNamePart;
|
|
||||||
public
|
|
||||||
Kind : TNameKind;
|
|
||||||
RefCount : Integer;
|
|
||||||
Id : AnsiString;
|
|
||||||
arrayexp : array of TExpression;
|
|
||||||
params : array of TFuncParam;
|
|
||||||
constructor Create(AKind: TNameKind);
|
|
||||||
procedure AddParam(prmtype: TEntity; prmname: TNamePart);
|
|
||||||
procedure AddArrayExpr(expr: TExpression);
|
|
||||||
property child: TNamePart read fchild write fChild; // int (*p)[10]; "[10]" is child of (*p)
|
|
||||||
property owner: TNamePart read fowner write fOwner;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function ParseNames(Parser: TTextParser; var NameType: TEntity; Names: TList; AllowMultipleNames: Boolean=True): Boolean;
|
function ParseNames(Parser: TTextParser; var NameType: TEntity; Names: TList; AllowMultipleNames: Boolean=True): Boolean;
|
||||||
function ParseName(Parser: TTextParser; var NameType: TEntity; var name: TNamePart): Boolean;
|
function ParseName(Parser: TTextParser; var NameType: TEntity; var name: TNamePart): Boolean;
|
||||||
|
|
||||||
@ -1458,8 +1466,6 @@ end;
|
|||||||
function ParseNextCEntity(AParser: TTextParser): TEntity;
|
function ParseNextCEntity(AParser: TTextParser): TEntity;
|
||||||
var
|
var
|
||||||
s : AnsiString;
|
s : AnsiString;
|
||||||
tt : TTokenType;
|
|
||||||
|
|
||||||
tp : TEntity;
|
tp : TEntity;
|
||||||
nm : TNamePart;
|
nm : TNamePart;
|
||||||
v : TVarFuncEntity;
|
v : TVarFuncEntity;
|
||||||
@ -1493,6 +1499,8 @@ begin
|
|||||||
end else
|
end else
|
||||||
Result:=v;
|
Result:=v;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if AParser.Token<>';' then ErrorExpect(AParser,';');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ErrorExpect(Parser:TTextParser;const Expect:AnsiString);
|
procedure ErrorExpect(Parser:TTextParser;const Expect:AnsiString);
|
||||||
@ -1644,7 +1652,7 @@ begin
|
|||||||
Parser.NextToken;
|
Parser.NextToken;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ParseNamePart(Parser: TTextParser): TNamePart;
|
function ParseCNamePart(Parser: TTextParser): TNamePart;
|
||||||
var
|
var
|
||||||
prefix : TNamePart;
|
prefix : TNamePart;
|
||||||
id : TNamePart;
|
id : TNamePart;
|
||||||
@ -2023,6 +2031,7 @@ end;
|
|||||||
|
|
||||||
initialization
|
initialization
|
||||||
ParseNextEntity:=@ParseNextCEntity;
|
ParseNextEntity:=@ParseNextCEntity;
|
||||||
|
ParseNamePart:=@ParseCNamePart;
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -81,6 +81,23 @@ function isNumberExp(x: TExpression; var v: Int64): Boolean;
|
|||||||
// int a[MAXCONST] -> a: array [0..MAXCONST-1] of Integer;
|
// int a[MAXCONST] -> a: array [0..MAXCONST-1] of Integer;
|
||||||
function PasArrayLimit(x: TExpression): AnsiString;
|
function PasArrayLimit(x: TExpression): AnsiString;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TStopComment }
|
||||||
|
|
||||||
|
TStopComment = class(TObject)
|
||||||
|
public
|
||||||
|
FirstComment : boolean;
|
||||||
|
CommentFound : boolean;
|
||||||
|
CommentEnd : Integer;
|
||||||
|
Precomp : TEntity;
|
||||||
|
PrecompEnd : Integer;
|
||||||
|
|
||||||
|
procedure OnComment(Sender: TObject; const Str: ansistring);
|
||||||
|
procedure OnPrecompiler(Sender: TTextParser; PrecompEntity: TObject);
|
||||||
|
procedure Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -114,7 +131,6 @@ type
|
|||||||
CmtList : TList;
|
CmtList : TList;
|
||||||
Breaker : TLineBreaker;
|
Breaker : TLineBreaker;
|
||||||
LastOffset : Integer;
|
LastOffset : Integer;
|
||||||
function FindCommentForLine(ln: Integer): TComment;
|
|
||||||
protected
|
protected
|
||||||
fWriters : TList;
|
fWriters : TList;
|
||||||
AuxTypeCounter : Integer;
|
AuxTypeCounter : Integer;
|
||||||
@ -140,7 +156,7 @@ type
|
|||||||
procedure WriteEnumAsConst(en: TEnumType; FinishWithInteger: Boolean=True);
|
procedure WriteEnumAsConst(en: TEnumType; FinishWithInteger: Boolean=True);
|
||||||
procedure WriteUnion(st: TUnionType);
|
procedure WriteUnion(st: TUnionType);
|
||||||
procedure WriteStruct(st: TStructType);
|
procedure WriteStruct(st: TStructType);
|
||||||
procedure WriteCommentToPas(cent: TComment);
|
procedure WriteCommentToPas(cent: TComment; NeedLineBreak: Boolean);
|
||||||
procedure WriteExp(x: TExpression);
|
procedure WriteExp(x: TExpression);
|
||||||
procedure WritePreprocessor(cent: TCPrepDefine);
|
procedure WritePreprocessor(cent: TCPrepDefine);
|
||||||
|
|
||||||
@ -239,22 +255,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
type
|
|
||||||
|
|
||||||
{ TStopComment }
|
{ TStopComment }
|
||||||
|
|
||||||
TStopComment = class(TObject)
|
|
||||||
public
|
|
||||||
FirstComment : boolean;
|
|
||||||
CommentFound : boolean;
|
|
||||||
CommentEnd : Integer;
|
|
||||||
Precomp : TEntity;
|
|
||||||
PrecompEnd : Integer;
|
|
||||||
|
|
||||||
procedure OnComment(Sender: TObject; const Str: ansistring);
|
|
||||||
procedure OnPrecompiler(Sender: TTextParser; PrecompEntity: TObject);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TStopComment.OnComment(Sender: TObject; const Str: ansistring);
|
procedure TStopComment.OnComment(Sender: TObject; const Str: ansistring);
|
||||||
var
|
var
|
||||||
parser: TTextParser;
|
parser: TTextParser;
|
||||||
@ -278,20 +280,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ParseNextEntityOrComment(AParser: TTextParser): TEntity;
|
procedure TStopComment.Clear;
|
||||||
|
begin
|
||||||
|
FirstComment:=False;
|
||||||
|
CommentFound:=False;
|
||||||
|
Precomp:=nil;
|
||||||
|
CommentEnd:=-1;
|
||||||
|
PrecompEnd:=-1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ParseNextEntityOrComment(AParser: TTextParser; cmt: TStopComment): TEntity;
|
||||||
var
|
var
|
||||||
cmt : TStopComment;
|
|
||||||
ent : TEntity;
|
ent : TEntity;
|
||||||
entidx : Integer;
|
entidx : Integer;
|
||||||
begin
|
begin
|
||||||
cmt := TStopComment.Create;
|
|
||||||
AParser.UseCommentEntities := True;
|
|
||||||
AParser.OnComment := @cmt.OnComment;
|
|
||||||
AParser.OnPrecompile:=@cmt.OnPrecompiler;
|
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
|
|
||||||
AParser.NextToken;
|
|
||||||
|
|
||||||
ent := ParseNextEntity(AParser);
|
ent := ParseNextEntity(AParser);
|
||||||
entidx := AParser.Index;
|
entidx := AParser.Index;
|
||||||
|
|
||||||
@ -306,11 +310,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
cmt.Free;
|
|
||||||
if (not Assigned(Result)) or (Assigned(ent) and (ent.Offset<Result.Offset)) then begin
|
if (not Assigned(Result)) or (Assigned(ent) and (ent.Offset<Result.Offset)) then begin
|
||||||
Result:=ent;
|
Result:=ent;
|
||||||
AParser.Index:=entidx;
|
AParser.Index:=entidx;
|
||||||
end;
|
end else
|
||||||
|
AParser.NextToken;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GetRefAsterix(const AstCount: integer): ansistring;
|
function GetRefAsterix(const AstCount: integer): ansistring;
|
||||||
@ -343,7 +347,6 @@ begin
|
|||||||
Result:=PasExp(x) + '-1';
|
Result:=PasExp(x) + '-1';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure WriteArray(arr: TNamePart; wr: TCodeWriter);
|
procedure WriteArray(arr: TNamePart; wr: TCodeWriter);
|
||||||
var
|
var
|
||||||
i : Integer;
|
i : Integer;
|
||||||
@ -353,7 +356,6 @@ begin
|
|||||||
wr.W(' of ');
|
wr.W(' of ');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TMacrosMaker = class(TObject)
|
TMacrosMaker = class(TObject)
|
||||||
public
|
public
|
||||||
@ -436,6 +438,7 @@ var
|
|||||||
owncfg : Boolean;
|
owncfg : Boolean;
|
||||||
lastsec : AnsiString; // last code section
|
lastsec : AnsiString; // last code section
|
||||||
ofs : Integer;
|
ofs : Integer;
|
||||||
|
cmt : TStopComment;
|
||||||
begin
|
begin
|
||||||
Result:='';
|
Result:='';
|
||||||
ent:=nil;
|
ent:=nil;
|
||||||
@ -447,13 +450,19 @@ begin
|
|||||||
|
|
||||||
if cfg.CustomDefines<>'' then PrepareMacros(cfg.CustomDefines, macros);
|
if cfg.CustomDefines<>'' then PrepareMacros(cfg.CustomDefines, macros);
|
||||||
|
|
||||||
|
cmt := TStopComment.Create;
|
||||||
p := CreateCParser(t);
|
p := CreateCParser(t);
|
||||||
p.MacroHandler:=macros;
|
p.MacroHandler:=macros;
|
||||||
|
p.UseCommentEntities := True;
|
||||||
|
p.OnComment := @cmt.OnComment;
|
||||||
|
p.OnPrecompile:=@cmt.OnPrecompiler;
|
||||||
|
|
||||||
try
|
try
|
||||||
repeat
|
repeat
|
||||||
try
|
try
|
||||||
ofs := p.Index;
|
ofs := p.Index;
|
||||||
ent := ParseNextEntityOrComment(p);
|
p.NextToken;
|
||||||
|
ent := ParseNextEntityOrComment(p, cmt);
|
||||||
except
|
except
|
||||||
ent:=nil;
|
ent:=nil;
|
||||||
end;
|
end;
|
||||||
@ -473,7 +482,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
cnv.WriteCtoPas(ent, p.Comments, t);
|
cnv.WriteCtoPas(ent, p.Comments, p.Buf);
|
||||||
|
|
||||||
lastsec:=cnv.wr.Section;
|
lastsec:=cnv.wr.Section;
|
||||||
except
|
except
|
||||||
@ -495,15 +504,14 @@ begin
|
|||||||
while i < p.Index do begin
|
while i < p.Index do begin
|
||||||
Inc(endPoint.Y);
|
Inc(endPoint.Y);
|
||||||
le := i;
|
le := i;
|
||||||
SkipLine(t, i);
|
SkipLine(p.Buf, i);
|
||||||
end;
|
end;
|
||||||
endPoint.X := p.Index - le + 1 + p.MacrosDelta;
|
endPoint.X := p.Index - le + 1 + p.MacrosDelta;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
finally
|
finally
|
||||||
p.Free;
|
p.Free;
|
||||||
macros.Free;
|
macros.Free;
|
||||||
|
cmt.Free;
|
||||||
end;
|
end;
|
||||||
except
|
except
|
||||||
on e: Exception do Result:=Result+LineEnding+' internal error: '+ e.Message;
|
on e: Exception do Result:=Result+LineEnding+' internal error: '+ e.Message;
|
||||||
@ -533,7 +541,7 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeConvertor.WriteCommentToPas(cent: TComment);
|
procedure TCodeConvertor.WriteCommentToPas(cent: TComment; NeedLineBreak: Boolean);
|
||||||
var
|
var
|
||||||
u: ansistring;
|
u: ansistring;
|
||||||
begin
|
begin
|
||||||
@ -541,12 +549,13 @@ begin
|
|||||||
if cent.CommenType = ctBlock then
|
if cent.CommenType = ctBlock then
|
||||||
begin
|
begin
|
||||||
u := StringReplace(u, '*)', '* )', [rfReplaceAll]);
|
u := StringReplace(u, '*)', '* )', [rfReplaceAll]);
|
||||||
wr.Wln('(*' + u + ' *)');
|
wr.W('(*' + u + ' *)');
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
wr.Wln('//' + u);
|
wr.W('//' + u);
|
||||||
end;
|
end;
|
||||||
|
if NeedLineBreak then wr.Wln;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeConvertor.WriteExp(x:TExpression);
|
procedure TCodeConvertor.WriteExp(x:TExpression);
|
||||||
@ -625,6 +634,9 @@ begin
|
|||||||
if m.Args[i].Name=''
|
if m.Args[i].Name=''
|
||||||
then PNames[i]:=cfg.ParamPrefix+IntToStr(i)
|
then PNames[i]:=cfg.ParamPrefix+IntToStr(i)
|
||||||
else PNames[i]:=m.Args[i].Name;
|
else PNames[i]:=m.Args[i].Name;
|
||||||
|
if not Assigned(m.Args[i].RetType) then
|
||||||
|
PTypes[i]:='id'
|
||||||
|
else
|
||||||
PTypes[i]:=GetPasTypeName(m.Args[i].RetType, m.Args[i].TypeName);
|
PTypes[i]:=GetPasTypeName(m.Args[i].RetType, m.Args[i].TypeName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -662,7 +674,6 @@ begin
|
|||||||
|
|
||||||
wr.W('procedure '+nm+'(AValue: '+tp+'); message '''+mtd+''';');
|
wr.W('procedure '+nm+'(AValue: '+tp+'); message '''+mtd+''';');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -675,14 +686,17 @@ begin
|
|||||||
for i:=0 to list.Count-1 do begin
|
for i:=0 to list.Count-1 do begin
|
||||||
ent:=TEntity(list[i]);
|
ent:=TEntity(list[i]);
|
||||||
if not Assigned(ent) then Continue;
|
if not Assigned(ent) then Continue;
|
||||||
|
|
||||||
WriteLnCommentsBeforeOffset(ent.Offset);
|
WriteLnCommentsBeforeOffset(ent.Offset);
|
||||||
if ent is TObjCMethod then
|
if ent is TObjCMethod then
|
||||||
WriteObjCMethod(TObjCMethod(ent))
|
WriteObjCMethod(TObjCMethod(ent))
|
||||||
else if ent is TObjCProperty then begin
|
else if ent is TObjCProperty then begin
|
||||||
WriteObjCProperty(TObjCProperty(ent));
|
WriteObjCProperty(TObjCProperty(ent));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
WriteLnCommentForOffset(ent.Offset);
|
WriteLnCommentForOffset(ent.Offset);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeConvertor.WriteObjCInterface(cent:TObjCInterface);
|
procedure TCodeConvertor.WriteObjCInterface(cent:TObjCInterface);
|
||||||
@ -696,7 +710,9 @@ const
|
|||||||
begin
|
begin
|
||||||
SetPasSection(wr, 'type');
|
SetPasSection(wr, 'type');
|
||||||
if cent.isCategory then begin
|
if cent.isCategory then begin
|
||||||
wr.W(cent.Name + ' = objccategory')
|
wr.W(cent.Name + ' = objccategory');
|
||||||
|
if cent.SuperClass<>'' then wr.W('('+cent.SuperClass+')');
|
||||||
|
wr.Wln;
|
||||||
end else begin
|
end else begin
|
||||||
wr.W(cent.Name + ' = objcclass');
|
wr.W(cent.Name + ' = objcclass');
|
||||||
if cent.SuperClass<>'' then wr.W('('+cent.SuperClass);
|
if cent.SuperClass<>'' then wr.W('('+cent.SuperClass);
|
||||||
@ -730,7 +746,7 @@ begin
|
|||||||
WriteObjCMethods(cent.Methods);
|
WriteObjCMethods(cent.Methods);
|
||||||
wr.DecIdent;
|
wr.DecIdent;
|
||||||
end;
|
end;
|
||||||
wr.Wln('end external;')
|
wr.Wln('end external;');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeConvertor.WriteObjCProtocol(cent:TObjCProtocol);
|
procedure TCodeConvertor.WriteObjCProtocol(cent:TObjCProtocol);
|
||||||
@ -738,7 +754,8 @@ var
|
|||||||
i : Integer;
|
i : Integer;
|
||||||
begin
|
begin
|
||||||
SetPasSection(wr, 'type');
|
SetPasSection(wr, 'type');
|
||||||
wr.W(cent.Name+'Protocol = objcprotocol');
|
if cent.Names.Count=1 then begin
|
||||||
|
wr.W(cent.Names[0]+'Protocol = objcprotocol');
|
||||||
|
|
||||||
if cent.Protocols.Count>0 then begin
|
if cent.Protocols.Count>0 then begin
|
||||||
wr.W('(');
|
wr.W('(');
|
||||||
@ -750,7 +767,11 @@ begin
|
|||||||
WriteObjCMethods(cent.Methods);
|
WriteObjCMethods(cent.Methods);
|
||||||
wr.DecIdent;
|
wr.DecIdent;
|
||||||
wr.W('end; ');
|
wr.W('end; ');
|
||||||
wr.Wln(' external name '''+cent.Name+''';');
|
wr.Wln(' external name '''+cent.Names[0]+''';');
|
||||||
|
end else begin
|
||||||
|
for i:=0 to cent.Names.Count-1 do
|
||||||
|
wr.Wln(cent.Names[i]+'Protocol = objcprotocol; external name '''+cent.Names[i]+''';');
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeConvertor.PushWriter;
|
procedure TCodeConvertor.PushWriter;
|
||||||
@ -808,13 +829,24 @@ end;
|
|||||||
procedure TCodeConvertor.WriteLnCommentForOffset(AOffset:Integer; NeedOffset: Boolean);
|
procedure TCodeConvertor.WriteLnCommentForOffset(AOffset:Integer; NeedOffset: Boolean);
|
||||||
var
|
var
|
||||||
cmt : TComment;
|
cmt : TComment;
|
||||||
|
ln : Integer;
|
||||||
|
c : Integer;
|
||||||
|
i : Integer;
|
||||||
begin
|
begin
|
||||||
cmt:=FindCommentForLine( Breaker.LineNumber(AOffset));
|
ln:= Breaker.LineNumber(AOffset);
|
||||||
if Assigned(cmt) then begin
|
c:=0;
|
||||||
|
for i:=0 to CmtList.Count-1 do begin
|
||||||
|
cmt:=TComment(CmtList[i]);
|
||||||
|
if Breaker.LineNumber(TComment(CmtList[i]).Offset)=ln then begin
|
||||||
|
if NeedOffset then begin
|
||||||
|
wr.W(' ');
|
||||||
|
NeedOffset:=False;
|
||||||
|
end;
|
||||||
|
WriteCommentToPas(cmt, false);
|
||||||
LastOffset:=cmt.Offset;
|
LastOffset:=cmt.Offset;
|
||||||
if NeedOffset then wr.W(' ');
|
inc(c);
|
||||||
WriteCommentToPas(cmt);
|
end;
|
||||||
end else
|
end;
|
||||||
wr.Wln;
|
wr.Wln;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1078,7 +1110,7 @@ begin
|
|||||||
wr.Wln(';');
|
wr.Wln(';');
|
||||||
end;
|
end;
|
||||||
end else if cent is TComment then
|
end else if cent is TComment then
|
||||||
WriteCommentToPas(cent as TComment)
|
WriteCommentToPas(cent as TComment, True)
|
||||||
else if cent is TCPrepDefine then
|
else if cent is TCPrepDefine then
|
||||||
WritePreprocessor(cent as TCPrepDefine)
|
WritePreprocessor(cent as TCPrepDefine)
|
||||||
else if cent is TObjCInterface then
|
else if cent is TObjCInterface then
|
||||||
@ -1332,20 +1364,7 @@ begin
|
|||||||
wr.W(PasTypeName + ' = ');}
|
wr.W(PasTypeName + ' = ');}
|
||||||
wr.W('todo: '+TypeEntity.ClassName);
|
wr.W('todo: '+TypeEntity.ClassName);
|
||||||
end;
|
end;
|
||||||
//todo: ...
|
//todo: ...parse any Entity
|
||||||
end;
|
|
||||||
|
|
||||||
function TCodeConvertor.FindCommentForLine(ln:Integer):TComment;
|
|
||||||
var
|
|
||||||
i : Integer;
|
|
||||||
begin
|
|
||||||
Result:=nil;
|
|
||||||
if not Assigned(CmtList) then Exit;
|
|
||||||
for i:=0 to CmtList.Count-1 do
|
|
||||||
if Breaker.LineNumber(TComment(CmtList[i]).Offset)=ln then begin
|
|
||||||
Result:=TComment(CmtList[i]);
|
|
||||||
Exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeConvertor.DefFuncWrite(wr:TCodeWriter;const FuncName,FuncRetType:AnsiString;
|
procedure TCodeConvertor.DefFuncWrite(wr:TCodeWriter;const FuncName,FuncRetType:AnsiString;
|
||||||
|
@ -26,6 +26,9 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, cparsertypes;
|
Classes, SysUtils, cparsertypes;
|
||||||
|
|
||||||
|
const
|
||||||
|
objcend = '@end';
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ TObjCClasses }
|
{ TObjCClasses }
|
||||||
@ -54,6 +57,7 @@ type
|
|||||||
RetName : TNamePart;
|
RetName : TNamePart;
|
||||||
Args : array of TObjCMethodArg;
|
Args : array of TObjCMethodArg;
|
||||||
Option : TObjCMethodOpt;
|
Option : TObjCMethodOpt;
|
||||||
|
VarParams : Boolean;
|
||||||
constructor Create(AOffset: Integer=-1); override;
|
constructor Create(AOffset: Integer=-1); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure AddArg(const ArgType: TEntity; ArgTypeName: TNamePart; const Name: AnsiString);
|
procedure AddArg(const ArgType: TEntity; ArgTypeName: TNamePart; const Name: AnsiString);
|
||||||
@ -88,7 +92,7 @@ type
|
|||||||
|
|
||||||
TObjCProtocol = class(TEntity)
|
TObjCProtocol = class(TEntity)
|
||||||
public
|
public
|
||||||
Name : AnsiString;
|
Names : TStringList;
|
||||||
isForward : Boolean;
|
isForward : Boolean;
|
||||||
Protocols : TStringList;
|
Protocols : TStringList;
|
||||||
Methods : TList;
|
Methods : TList;
|
||||||
@ -113,7 +117,7 @@ function ParseClassList(AParser: TTextParser): TObjCClasses;
|
|||||||
function ParseInterface(AParser: TTextParser): TObjCInterface;
|
function ParseInterface(AParser: TTextParser): TObjCInterface;
|
||||||
function ParseMethod(AParser: TTextParser): TObjCMethod;
|
function ParseMethod(AParser: TTextParser): TObjCMethod;
|
||||||
function ParseProperty(AParser: TTextParser): TObjCProperty;
|
function ParseProperty(AParser: TTextParser): TObjCProperty;
|
||||||
function ParseMethods(AParser: TTextParser; MethodsList: TList; const EndToken: AnsiString): Boolean;
|
function ParseMethods(AParser: TTextParser; MethodsList: TList; const EndToken: AnsiString = objcend): Boolean;
|
||||||
function ParseProtocol(AParser: TTextParser): TEntity;
|
function ParseProtocol(AParser: TTextParser): TEntity;
|
||||||
|
|
||||||
function ParseNextObjCEntity(AParser: TTextParser): TEntity;
|
function ParseNextObjCEntity(AParser: TTextParser): TEntity;
|
||||||
@ -121,6 +125,9 @@ function ParseNextObjCEntity(AParser: TTextParser): TEntity;
|
|||||||
function isObjCKeyword(const token: AnsiString): Boolean; inline;
|
function isObjCKeyword(const token: AnsiString): Boolean; inline;
|
||||||
function GetObjCKeyword(const token: AnsiString): AnsiString;
|
function GetObjCKeyword(const token: AnsiString): AnsiString;
|
||||||
|
|
||||||
|
const
|
||||||
|
nk_Protocol = $1000;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function isObjCKeyword(const token: AnsiString): Boolean; inline;
|
function isObjCKeyword(const token: AnsiString): Boolean; inline;
|
||||||
@ -140,6 +147,7 @@ var
|
|||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
if AParser.Token<>'@class' then Exit;
|
if AParser.Token<>'@class' then Exit;
|
||||||
|
try
|
||||||
cl:=TObjCClasses.Create(AParser.TokenPos);
|
cl:=TObjCClasses.Create(AParser.TokenPos);
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
while AParser.Token<>';' do begin
|
while AParser.Token<>';' do begin
|
||||||
@ -158,7 +166,11 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
if AParser.Token<>';' then ErrorExpect(AParser, ';');
|
||||||
Result:=cl;
|
Result:=cl;
|
||||||
|
finally
|
||||||
|
if not Assigned(Result) then cl.Free;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ParseInstVars(AParser: TTextParser; Vars: TList): Boolean;
|
function ParseInstVars(AParser: TTextParser; Vars: TList): Boolean;
|
||||||
@ -217,14 +229,14 @@ begin
|
|||||||
|
|
||||||
itf:=TObjCInterface.Create(i);
|
itf:=TObjCInterface.Create(i);
|
||||||
try
|
try
|
||||||
itf.Name:=nm;
|
|
||||||
itf.isCategory:=AParser.Token='(';
|
itf.isCategory:=AParser.Token='(';
|
||||||
if itf.isCategory then begin
|
if itf.isCategory then begin
|
||||||
|
itf.SuperClass:=nm;
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
if not ConsumeIdentifier(AParser, itf.SuperClass) and ConsumeToken(AParser, ')') then
|
if not (ConsumeIdentifier(AParser, itf.Name) and ConsumeToken(AParser, ')')) then
|
||||||
Exit;
|
Exit;
|
||||||
end else begin
|
end else begin
|
||||||
|
itf.Name:=nm;
|
||||||
// super-class
|
// super-class
|
||||||
if AParser.Token=':' then begin
|
if AParser.Token=':' then begin
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
@ -249,8 +261,8 @@ begin
|
|||||||
ParseInstVars(AParser, itf.Vars);
|
ParseInstVars(AParser, itf.Vars);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if not ParseMethods(AParser, itf.Methods, '@end') then Exit;
|
if not ParseMethods(AParser, itf.Methods, objcend) then Exit;
|
||||||
if AParser.Token='@end' then AParser.NextToken;
|
if AParser.Token<>objcend then ErrorExpect(AParser, objcend);
|
||||||
|
|
||||||
Result:=itf;
|
Result:=itf;
|
||||||
finally
|
finally
|
||||||
@ -268,11 +280,17 @@ begin
|
|||||||
p := TObjCProtocol.Create(AParser.TokenPos);
|
p := TObjCProtocol.Create(AParser.TokenPos);
|
||||||
try
|
try
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
if not ConsumeIdentifier(AParser, p.Name) then Exit;
|
if not ConsumeIdentifier(AParser, nm) then Exit;
|
||||||
p.isForward:= AParser.Token=';';
|
p.Names.Add(nm);
|
||||||
|
p.isForward:= (AParser.Token=';') or (AParser.Token=',');
|
||||||
if p.isForward then begin
|
if p.isForward then begin
|
||||||
Result:=p;
|
while AParser.Token<>';' do begin
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
|
ConsumeIdentifier(AParser, nm);
|
||||||
|
p.Names.Add(nm);
|
||||||
|
end;
|
||||||
|
Result:=p;
|
||||||
|
if AParser.Token<>';' then ErrorExpect(AParser, ';');
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -286,8 +304,8 @@ begin
|
|||||||
if AParser.Token='>' then AParser.NextToken;
|
if AParser.Token='>' then AParser.NextToken;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if ParseMethods(AParser, p.Methods, '@end') then Result:=p;
|
if ParseMethods(AParser, p.Methods, objcend) then Result:=p;
|
||||||
if AParser.Token='@end' then AParser.NextToken;
|
if AParser.Token<>objcend then ErrorExpect(AParser, objcend);
|
||||||
finally
|
finally
|
||||||
if not Assigned(Result) then p.Free;
|
if not Assigned(Result) then p.Free;
|
||||||
end;
|
end;
|
||||||
@ -295,6 +313,7 @@ end;
|
|||||||
|
|
||||||
var
|
var
|
||||||
PrevParseNextEntity : function (AParser: TTextParser): TEntity = nil;
|
PrevParseNextEntity : function (AParser: TTextParser): TEntity = nil;
|
||||||
|
PrevNamePart : function (AParser: TTextParser): TNamePart = nil;
|
||||||
|
|
||||||
function ParseNextObjCEntity(AParser: TTextParser): TEntity;
|
function ParseNextObjCEntity(AParser: TTextParser): TEntity;
|
||||||
var
|
var
|
||||||
@ -377,25 +396,36 @@ begin
|
|||||||
m.Name.Add(nm+':');
|
m.Name.Add(nm+':');
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
|
|
||||||
while AParser.Token<>';' do begin
|
while (AParser.Token<>';') and (AParser.Token<>',') do begin
|
||||||
|
if AParser.Token='(' then begin
|
||||||
prm:=ConsumeToken(AParser, '(') and
|
prm:=ConsumeToken(AParser, '(') and
|
||||||
ParseName(APArser, atype, atname) and
|
ParseName(APArser, atype, atname) and
|
||||||
ConsumeToken(AParser, ')') and
|
ConsumeToken(AParser, ')');
|
||||||
ConsumeIdentifier(AParser, aname);
|
end else begin
|
||||||
|
prm:=True;
|
||||||
|
atype:=nil;
|
||||||
|
atname:=nil;
|
||||||
|
end;
|
||||||
if not prm then Exit;
|
if not prm then Exit;
|
||||||
|
ConsumeIdentifier(AParser, aname);
|
||||||
m.AddArg(atype, atname, aname);
|
m.AddArg(atype, atname, aname);
|
||||||
|
|
||||||
|
// the next name starts
|
||||||
if AParser.TokenType=tt_Ident then ConsumeIdentifier(AParser, nm) else nm:='';
|
if AParser.TokenType=tt_Ident then ConsumeIdentifier(AParser, nm) else nm:='';
|
||||||
if AParser.Token<>';' then begin
|
if (AParser.Token<>';') and (AParser.Token<>',') then begin
|
||||||
if not ConsumeToken(AParser,':') then Exit;
|
if not ConsumeToken(AParser,':') then Exit;
|
||||||
m.Name.Add(nm+':');
|
m.Name.Add(nm+':');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
AParser.NextToken;
|
end else
|
||||||
end else begin
|
|
||||||
m.Name.Add(nm);
|
m.Name.Add(nm);
|
||||||
if not ConsumeToken(AParser, ';') then Exit;
|
|
||||||
|
if AParser.Token=',' then begin
|
||||||
|
AParser.NextToken;
|
||||||
|
if ConsumeToken(AParser,'...') then m.VarParams:=True
|
||||||
|
else ErrorExpect(AParser, '...');
|
||||||
end;
|
end;
|
||||||
|
if not ConsumeToken(AParser, ';') then Exit;
|
||||||
|
|
||||||
Result:=m;
|
Result:=m;
|
||||||
finally
|
finally
|
||||||
@ -403,7 +433,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ParseMethods(AParser: TTextParser; MethodsList: TList; const EndToken: AnsiString = '@end'): Boolean;
|
function ParseMethods(AParser: TTextParser; MethodsList: TList; const EndToken: AnsiString): Boolean;
|
||||||
var
|
var
|
||||||
m : TObjCMethod;
|
m : TObjCMethod;
|
||||||
p : TObjCProperty;
|
p : TObjCProperty;
|
||||||
@ -484,6 +514,7 @@ begin
|
|||||||
inherited Create(AOffset);
|
inherited Create(AOffset);
|
||||||
Protocols := TStringList.Create;
|
Protocols := TStringList.Create;
|
||||||
Methods := TList.Create;
|
Methods := TList.Create;
|
||||||
|
Names := TStringList.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TObjCProtocol.Destroy;
|
destructor TObjCProtocol.Destroy;
|
||||||
@ -493,6 +524,7 @@ begin
|
|||||||
for i:=0 to Methods.Count-1 do TObject(Methods[i]).Free;
|
for i:=0 to Methods.Count-1 do TObject(Methods[i]).Free;
|
||||||
Methods.Free;
|
Methods.Free;
|
||||||
Protocols.Free;
|
Protocols.Free;
|
||||||
|
Names.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -521,7 +553,7 @@ begin
|
|||||||
Result:=nil;
|
Result:=nil;
|
||||||
if AParser.Token<>'@property' then Exit;
|
if AParser.Token<>'@property' then Exit;
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
p := TObjCProperty.Create;
|
p := TObjCProperty.Create(AParser.TokenPos);
|
||||||
try
|
try
|
||||||
if AParser.Token='(' then begin
|
if AParser.Token='(' then begin
|
||||||
AParser.NextToken;
|
AParser.NextToken;
|
||||||
@ -556,9 +588,25 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function ParseObjCNamePart(AParser: TTextParser): TNamePart;
|
||||||
|
var
|
||||||
|
p : AnsiString;
|
||||||
|
begin
|
||||||
|
// skipping protocol adopted type definition
|
||||||
|
if AParser.Token='<' then begin
|
||||||
|
Result:=nil;
|
||||||
|
AParser.NextToken;
|
||||||
|
if not (ConsumeIdentifier(AParser, p) and ConsumeToken(AParser,'>')) then Exit;
|
||||||
|
end;
|
||||||
|
Result:=PrevNamePart(AParser);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
PrevParseNextEntity:=ParseNextEntity;
|
PrevParseNextEntity:=ParseNextEntity;
|
||||||
ParseNextEntity:=ParseNextObjCEntity;
|
ParseNextEntity:=ParseNextObjCEntity;
|
||||||
|
|
||||||
|
PrevNamePart:=ParseNamePart;
|
||||||
|
ParseNamePart:=ParseObjCNamePart;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user