mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 01:39:26 +02:00
Patch from IvankoB on Yandex.Ru to add support for REINTRODUCE, DEPRECATED, STATIC, OVERRIDE, MESSAGE modifiers
git-svn-id: trunk@3172 -
This commit is contained in:
parent
a5a8741464
commit
b3f6041d55
@ -346,7 +346,7 @@ type
|
|||||||
function GetDeclaration(full: Boolean): string; override;
|
function GetDeclaration(full: Boolean): string; override;
|
||||||
procedure GetModifiers(List: TStrings);
|
procedure GetModifiers(List: TStrings);
|
||||||
IsVirtual, IsDynamic, IsAbstract, IsOverride,
|
IsVirtual, IsDynamic, IsAbstract, IsOverride,
|
||||||
IsOverload, IsMessage: Boolean;
|
IsOverload, IsMessage, isReintroduced, isStatic: Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TPasFunction = class(TPasProcedure)
|
TPasFunction = class(TPasProcedure)
|
||||||
@ -1374,6 +1374,8 @@ begin
|
|||||||
DoAdd(IsOverride,' Override');
|
DoAdd(IsOverride,' Override');
|
||||||
DoAdd(IsAbstract,' Abstract');
|
DoAdd(IsAbstract,' Abstract');
|
||||||
DoAdd(IsOverload,' Overload');
|
DoAdd(IsOverload,' Overload');
|
||||||
|
DoAdd(IsReintroduced,' Reintroduce');
|
||||||
|
DoAdd(IsStatic,' Static');
|
||||||
DoAdd(IsMessage,' Message');
|
DoAdd(IsMessage,' Message');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1421,16 +1421,41 @@ begin
|
|||||||
{ El['calling-conv'] := 'cdecl';}
|
{ El['calling-conv'] := 'cdecl';}
|
||||||
ExpectToken(tkSemicolon);
|
ExpectToken(tkSemicolon);
|
||||||
end
|
end
|
||||||
|
else if (Tok='PASCAL') then
|
||||||
|
begin
|
||||||
|
{ El['calling-conv'] := 'pascal';}
|
||||||
|
ExpectToken(tkSemicolon);
|
||||||
|
end
|
||||||
else if (Tok='STDCALL') then
|
else if (Tok='STDCALL') then
|
||||||
begin
|
begin
|
||||||
{ El['calling-conv'] := 'stdcall';}
|
{ El['calling-conv'] := 'stdcall';}
|
||||||
ExpectToken(tkSemicolon);
|
ExpectToken(tkSemicolon);
|
||||||
end
|
end
|
||||||
|
else if (Tok='OLDFPCCALL') then
|
||||||
|
begin
|
||||||
|
{ El['calling-conv'] := 'oldfpccall';}
|
||||||
|
ExpectToken(tkSemicolon);
|
||||||
|
end
|
||||||
|
else if (Tok='EXTDECL') then
|
||||||
|
begin
|
||||||
|
{ El['calling-conv'] := 'extdecl';}
|
||||||
|
ExpectToken(tkSemicolon);
|
||||||
|
end
|
||||||
|
else if (Tok='REGISTER') then
|
||||||
|
begin
|
||||||
|
{ El['calling-conv'] := 'register';}
|
||||||
|
ExpectToken(tkSemicolon);
|
||||||
|
end
|
||||||
else if (Tok='COMPILERPROC') then
|
else if (Tok='COMPILERPROC') then
|
||||||
begin
|
begin
|
||||||
{ El['calling-conv'] := 'compilerproc';}
|
{ El['calling-conv'] := 'compilerproc';}
|
||||||
ExpectToken(tkSemicolon);
|
ExpectToken(tkSemicolon);
|
||||||
end
|
end
|
||||||
|
else if (Tok='VARARGS') then
|
||||||
|
begin
|
||||||
|
{ 'varargs': needs CDECL & EXTERNAL }
|
||||||
|
ExpectToken(tkSemicolon);
|
||||||
|
end
|
||||||
else if (tok='DEPRECATED') then
|
else if (tok='DEPRECATED') then
|
||||||
begin
|
begin
|
||||||
{ El['calling-conv'] := 'deprecated';}
|
{ El['calling-conv'] := 'deprecated';}
|
||||||
@ -1445,6 +1470,10 @@ begin
|
|||||||
begin
|
begin
|
||||||
ExpectToken(tkSemicolon);
|
ExpectToken(tkSemicolon);
|
||||||
end
|
end
|
||||||
|
else if (tok='ASSEMBLER') then
|
||||||
|
begin
|
||||||
|
ExpectToken(tkSemicolon);
|
||||||
|
end
|
||||||
else if (UpperCase(CurTokenString) = 'EXTERNAL') then
|
else if (UpperCase(CurTokenString) = 'EXTERNAL') then
|
||||||
repeat
|
repeat
|
||||||
NextToken;
|
NextToken;
|
||||||
@ -1482,116 +1511,184 @@ procedure TPasParser.ParseProperty(Element:TPasElement);
|
|||||||
begin
|
begin
|
||||||
ExpectIdentifier;
|
ExpectIdentifier;
|
||||||
Result := CurTokenString;
|
Result := CurTokenString;
|
||||||
while True do
|
|
||||||
begin
|
while True do begin
|
||||||
NextToken;
|
NextToken;
|
||||||
if CurToken = tkDot then
|
if CurToken = tkDot then begin
|
||||||
begin
|
|
||||||
ExpectIdentifier;
|
ExpectIdentifier;
|
||||||
Result := Result + '.' + CurTokenString;
|
Result := Result + '.' + CurTokenString;
|
||||||
end else
|
end else
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
UngetToken;
|
|
||||||
|
if CurToken = tkSquaredBraceOpen then begin
|
||||||
|
Result := Result + '[';
|
||||||
|
NextToken;
|
||||||
|
if CurToken in [tkIdentifier, tkNumber] then begin
|
||||||
|
Result := Result + CurTokenString;
|
||||||
|
end;
|
||||||
|
ExpectToken(tkSquaredBraceClose);
|
||||||
|
Result := Result + ']';
|
||||||
|
end else
|
||||||
|
UngetToken;
|
||||||
|
|
||||||
|
// writeln(Result);
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
NextToken;
|
NextToken;
|
||||||
// !!!: Parse array properties correctly
|
// if array prop then parse [ arg1:type1;... ]
|
||||||
if CurToken = tkSquaredBraceOpen then
|
if CurToken = tkSquaredBraceOpen then begin
|
||||||
begin
|
// !!!: Parse array properties correctly
|
||||||
ParseArgList(Element, TPasProperty(Element).Args, tkSquaredBraceClose);
|
ParseArgList(Element, TPasProperty(Element).Args, tkSquaredBraceClose);
|
||||||
NextToken;
|
NextToken;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if CurToken = tkColon then
|
if CurToken = tkColon then begin
|
||||||
begin
|
// if ":prop_data_type" if supplied then read it
|
||||||
// read property type
|
// read property type
|
||||||
TPasProperty(Element).VarType := ParseType(Element);
|
TPasProperty(Element).VarType := ParseType(Element);
|
||||||
NextToken;
|
NextToken;
|
||||||
end;
|
end;
|
||||||
if CurToken <> tkSemicolon then
|
|
||||||
begin
|
if CurToken <> tkSemicolon then begin
|
||||||
// read 'index' access modifier
|
// if indexed prop then read the index value
|
||||||
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'INDEX') then
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'INDEX') then
|
||||||
TPasProperty(Element).IndexValue := ParseExpression
|
// read 'index' access modifier
|
||||||
else
|
TPasProperty(Element).IndexValue := ParseExpression
|
||||||
UngetToken;
|
else
|
||||||
NextToken;
|
// not indexed prop will be recheck for another token
|
||||||
|
UngetToken;
|
||||||
|
|
||||||
|
NextToken;
|
||||||
end;
|
end;
|
||||||
if CurToken <> tkSemicolon then
|
|
||||||
begin
|
// if the accessors list is not finished
|
||||||
// read 'read' access modifier
|
if CurToken <> tkSemicolon then begin
|
||||||
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'READ') then
|
// read 'read' access modifier
|
||||||
TPasProperty(Element).ReadAccessorName := GetAccessorName
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'READ') then
|
||||||
else
|
TPasProperty(Element).ReadAccessorName := GetAccessorName
|
||||||
UngetToken;
|
else
|
||||||
NextToken;
|
// not read accessor will be recheck for another token
|
||||||
|
UngetToken;
|
||||||
|
|
||||||
|
NextToken;
|
||||||
end;
|
end;
|
||||||
if CurToken <> tkSemicolon then
|
|
||||||
begin
|
// if the accessors list is not finished
|
||||||
// read 'write' access modifier
|
if CurToken <> tkSemicolon then begin
|
||||||
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'WRITE') then
|
// read 'write' access modifier
|
||||||
TPasProperty(Element).WriteAccessorName := GetAccessorName
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'WRITE') then
|
||||||
else
|
TPasProperty(Element).WriteAccessorName := GetAccessorName
|
||||||
UngetToken;
|
else
|
||||||
NextToken;
|
// not write accessor will be recheck for another token
|
||||||
|
UngetToken;
|
||||||
|
|
||||||
|
NextToken;
|
||||||
end;
|
end;
|
||||||
if CurToken <> tkSemicolon then
|
|
||||||
begin
|
// if the specifiers list is not finished
|
||||||
// read 'stored' access modifier
|
if CurToken <> tkSemicolon then begin
|
||||||
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'STORED') then
|
// read 'stored' access modifier
|
||||||
begin
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'STORED') then begin
|
||||||
NextToken;
|
NextToken;
|
||||||
if CurToken = tkTrue then
|
if CurToken = tkTrue then
|
||||||
TPasProperty(Element).StoredAccessorName := 'True'
|
TPasProperty(Element).StoredAccessorName := 'True'
|
||||||
else if CurToken = tkFalse then
|
else if CurToken = tkFalse then
|
||||||
TPasProperty(Element).StoredAccessorName := 'False'
|
TPasProperty(Element).StoredAccessorName := 'False'
|
||||||
else if CurToken = tkIdentifier then
|
else if CurToken = tkIdentifier then
|
||||||
TPasProperty(Element).StoredAccessorName := CurTokenString
|
TPasProperty(Element).StoredAccessorName := CurTokenString
|
||||||
else
|
else
|
||||||
ParseExc(SParserSyntaxError);
|
ParseExc(SParserSyntaxError);
|
||||||
|
end else
|
||||||
|
// not stored accessor will be recheck for another token
|
||||||
|
UngetToken;
|
||||||
|
|
||||||
|
NextToken;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// if the specifiers list is not finished
|
||||||
|
if CurToken <> tkSemicolon then begin
|
||||||
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then
|
||||||
|
// read 'default' value modifier -> ParseExpression(DEFAULT <value>)
|
||||||
|
TPasProperty(Element).DefaultValue := ParseExpression
|
||||||
|
else
|
||||||
|
// not "default <value>" prop will be recheck for another token
|
||||||
|
UngetToken;
|
||||||
|
|
||||||
|
NextToken;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// if the specifiers list is not finished
|
||||||
|
if CurToken <> tkSemicolon then begin
|
||||||
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'NODEFAULT') then begin
|
||||||
|
// read 'nodefault' modifier
|
||||||
|
TPasProperty(Element).IsNodefault:=true;
|
||||||
|
end;
|
||||||
|
// stop recheck for specifiers - start from next token
|
||||||
|
NextToken;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// after NODEFAULT may be a ";"
|
||||||
|
if CurToken = tkSemicolon then begin
|
||||||
|
// read semicolon
|
||||||
|
NextToken;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then begin
|
||||||
|
// what is after DEFAULT token at the end
|
||||||
|
NextToken;
|
||||||
|
if CurToken = tkSemicolon then begin
|
||||||
|
// ";" then DEFAULT=prop
|
||||||
|
TPasProperty(Element).IsDefault := True;
|
||||||
|
UngetToken;
|
||||||
|
end else begin
|
||||||
|
// "!;" then a step back to get phrase "DEFAULT <value>"
|
||||||
|
UngetToken;
|
||||||
|
// DefaultValue -> ParseExpression(DEFAULT <value>) and stay on the <value>
|
||||||
|
TPasProperty(Element).DefaultValue := ParseExpression;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//!! there may be DEPRECATED token
|
||||||
|
NextToken;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
// after DEFAULT may be a ";"
|
||||||
|
if CurToken = tkSemicolon then begin
|
||||||
|
// read semicolon
|
||||||
|
NextToken;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEPRECATED') then begin
|
||||||
|
// nothing to do on DEPRECATED - just to accept
|
||||||
|
// NextToken;
|
||||||
end else
|
end else
|
||||||
UngetToken;
|
UngetToken;;
|
||||||
NextToken;
|
|
||||||
|
//!! else
|
||||||
|
// not DEFAULT prop accessor will be recheck for another token
|
||||||
|
//!! UngetToken;
|
||||||
|
|
||||||
|
{
|
||||||
|
if CurToken = tkSemicolon then begin
|
||||||
|
// read semicolon
|
||||||
|
NextToken;
|
||||||
end;
|
end;
|
||||||
if CurToken <> tkSemicolon then
|
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEPRECATED') then begin
|
||||||
begin
|
// nothing to do - just to process
|
||||||
// read 'default' value modifier
|
NextToken;
|
||||||
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then
|
|
||||||
TPasProperty(Element).DefaultValue := ParseExpression
|
|
||||||
else
|
|
||||||
UngetToken;
|
|
||||||
NextToken;
|
|
||||||
end;
|
end;
|
||||||
if CurToken <> tkSemicolon then
|
if CurToken = tkSemicolon then begin
|
||||||
begin
|
// read semicolon
|
||||||
// read 'nodefault' modifier
|
NextToken;
|
||||||
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'NODEFAULT') then
|
|
||||||
begin
|
|
||||||
TPasProperty(Element).IsNodefault:=true;
|
|
||||||
end;
|
end;
|
||||||
NextToken;
|
}
|
||||||
end;
|
|
||||||
if CurToken = tkSemicolon then
|
|
||||||
begin
|
|
||||||
// read semicolon
|
|
||||||
NextToken;
|
|
||||||
end;
|
|
||||||
if (CurToken = tkIdentifier) and (UpperCase(CurTokenText) = 'DEFAULT') then
|
|
||||||
begin
|
|
||||||
NextToken;
|
|
||||||
if CurToken = tkSemicolon then
|
|
||||||
begin
|
|
||||||
TPasProperty(Element).IsDefault := True;
|
|
||||||
UngetToken;
|
|
||||||
end else
|
|
||||||
begin
|
|
||||||
UngetToken;
|
|
||||||
TPasProperty(Element).DefaultValue := ParseExpression;
|
|
||||||
end;
|
|
||||||
end else
|
|
||||||
UngetToken;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1782,19 +1879,31 @@ var
|
|||||||
Proc.IsAbstract := True
|
Proc.IsAbstract := True
|
||||||
else if s = 'OVERRIDE' then
|
else if s = 'OVERRIDE' then
|
||||||
Proc.IsOverride := True
|
Proc.IsOverride := True
|
||||||
|
else if s = 'REINTRODUCE' then
|
||||||
|
Proc.IsReintroduced := True
|
||||||
else if s = 'OVERLOAD' then
|
else if s = 'OVERLOAD' then
|
||||||
Proc.IsOverload := True
|
Proc.IsOverload := True
|
||||||
else if s = 'MESSAGE' then
|
else if s = 'STATIC' then
|
||||||
begin
|
Proc.IsStatic := True
|
||||||
|
else if s = 'MESSAGE' then begin
|
||||||
Proc.IsMessage := True;
|
Proc.IsMessage := True;
|
||||||
repeat
|
repeat
|
||||||
NextToken;
|
NextToken;
|
||||||
until CurToken = tkSemicolon;
|
until CurToken = tkSemicolon;
|
||||||
UngetToken;
|
UngetToken;
|
||||||
end else if s = 'CDECL' then
|
end
|
||||||
|
else if s = 'CDECL' then
|
||||||
|
{ El['calling-conv'] := 'cdecl';}
|
||||||
|
else if s = 'PASCAL' then
|
||||||
{ El['calling-conv'] := 'cdecl';}
|
{ El['calling-conv'] := 'cdecl';}
|
||||||
else if s = 'STDCALL' then
|
else if s = 'STDCALL' then
|
||||||
{ El['calling-conv'] := 'stdcall';}
|
{ El['calling-conv'] := 'stdcall';}
|
||||||
|
else if s = 'OLDFPCCALL' then
|
||||||
|
{ El['calling-conv'] := 'oldfpccall';}
|
||||||
|
else if s = 'EXTDECL' then
|
||||||
|
{ El['calling-conv'] := 'extdecl';}
|
||||||
|
else if s = 'DEPRECATED' then
|
||||||
|
{ El['calling-conv'] := 'deprecated';}
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
UngetToken;
|
UngetToken;
|
||||||
|
Loading…
Reference in New Issue
Block a user