mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 01:09:25 +02:00
fcl-passrc: parse and resolve method modifier message
git-svn-id: trunk@41582 -
This commit is contained in:
parent
72196141b0
commit
cbdd7e892f
@ -181,7 +181,7 @@ const
|
|||||||
nDerivedXMustExtendASubClassY = 3115;
|
nDerivedXMustExtendASubClassY = 3115;
|
||||||
nDefaultPropertyNotAllowedInHelperForX = 3116;
|
nDefaultPropertyNotAllowedInHelperForX = 3116;
|
||||||
nHelpersCannotBeUsedAsTypes = 3117;
|
nHelpersCannotBeUsedAsTypes = 3117;
|
||||||
// free 3118
|
nMessageHandlersInvalidParams = 3118;
|
||||||
nImplictConversionUnicodeToAnsi = 3119;
|
nImplictConversionUnicodeToAnsi = 3119;
|
||||||
nWrongTypeXInArrayConstructor = 3120;
|
nWrongTypeXInArrayConstructor = 3120;
|
||||||
nUnknownCustomAttributeX = 3121;
|
nUnknownCustomAttributeX = 3121;
|
||||||
@ -315,7 +315,7 @@ resourcestring
|
|||||||
sDerivedXMustExtendASubClassY = 'Derived %s must extend a subclass of "%s" or the class itself';
|
sDerivedXMustExtendASubClassY = 'Derived %s must extend a subclass of "%s" or the class itself';
|
||||||
sDefaultPropertyNotAllowedInHelperForX = 'Default property not allowed in helper for %s';
|
sDefaultPropertyNotAllowedInHelperForX = 'Default property not allowed in helper for %s';
|
||||||
sHelpersCannotBeUsedAsTypes = 'helpers cannot be used as types';
|
sHelpersCannotBeUsedAsTypes = 'helpers cannot be used as types';
|
||||||
// was 3118
|
sMessageHandlersInvalidParams = 'Message handlers can take only one call by ref. parameter';
|
||||||
sImplictConversionUnicodeToAnsi = 'Implicit string type conversion with potential data loss from "UnicodeString" to "AnsiString"';
|
sImplictConversionUnicodeToAnsi = 'Implicit string type conversion with potential data loss from "UnicodeString" to "AnsiString"';
|
||||||
sWrongTypeXInArrayConstructor = 'Wrong type "%s" in array constructor';
|
sWrongTypeXInArrayConstructor = 'Wrong type "%s" in array constructor';
|
||||||
sUnknownCustomAttributeX = 'Unknown custom attribute "%s"';
|
sUnknownCustomAttributeX = 'Unknown custom attribute "%s"';
|
||||||
|
@ -5847,6 +5847,8 @@ var
|
|||||||
ObjKind: TPasObjKind;
|
ObjKind: TPasObjKind;
|
||||||
ParentBody: TProcedureBody;
|
ParentBody: TProcedureBody;
|
||||||
HelperForType: TPasType;
|
HelperForType: TPasType;
|
||||||
|
Args: TFPList;
|
||||||
|
Arg: TPasArgument;
|
||||||
begin
|
begin
|
||||||
if El.Parent is TPasProcedure then
|
if El.Parent is TPasProcedure then
|
||||||
Proc:=TPasProcedure(El.Parent)
|
Proc:=TPasProcedure(El.Parent)
|
||||||
@ -6046,10 +6048,28 @@ begin
|
|||||||
if El is TPasFunctionType then
|
if El is TPasFunctionType then
|
||||||
EmitTypeHints(TPasFunctionType(El).ResultEl,TPasFunctionType(El).ResultEl.ResultType);
|
EmitTypeHints(TPasFunctionType(El).ResultEl,TPasFunctionType(El).ResultEl.ResultType);
|
||||||
|
|
||||||
|
if Proc.PublicName<>nil then
|
||||||
|
ResolveExpr(Proc.PublicName,rraRead);
|
||||||
if Proc.LibraryExpr<>nil then
|
if Proc.LibraryExpr<>nil then
|
||||||
ResolveExpr(Proc.LibraryExpr,rraRead);
|
ResolveExpr(Proc.LibraryExpr,rraRead);
|
||||||
if Proc.LibrarySymbolName<>nil then
|
if Proc.LibrarySymbolName<>nil then
|
||||||
ResolveExpr(Proc.LibrarySymbolName,rraRead);
|
ResolveExpr(Proc.LibrarySymbolName,rraRead);
|
||||||
|
if Proc.DispIDExpr<>nil then
|
||||||
|
ResolveExpr(Proc.DispIDExpr,rraRead);
|
||||||
|
if Proc.MessageExpr<>nil then
|
||||||
|
begin
|
||||||
|
// message modifier
|
||||||
|
ResolveExpr(Proc.MessageExpr,rraRead);
|
||||||
|
Args:=Proc.ProcType.Args;
|
||||||
|
if Args.Count<>1 then
|
||||||
|
RaiseMsg(20190303223701,nMessageHandlersInvalidParams,sMessageHandlersInvalidParams,[],El);
|
||||||
|
Arg:=TPasArgument(Args[0]);
|
||||||
|
if not (Arg.Access in [argVar,argOut]) then
|
||||||
|
RaiseMsg(20190303223834,nMessageHandlersInvalidParams,sMessageHandlersInvalidParams,[],El);
|
||||||
|
if (Proc.ClassType<>TPasProcedure)
|
||||||
|
and (Proc.ClassType<>TPasFunction) then
|
||||||
|
RaiseMsg(20190303224128,nXExpectedButYFound,sXExpectedButYFound,['procedure name(var Msg);message id;',GetElementTypeName(El)],El);
|
||||||
|
end;
|
||||||
|
|
||||||
if Proc.Parent is TPasMembersType then
|
if Proc.Parent is TPasMembersType then
|
||||||
begin
|
begin
|
||||||
|
@ -1054,6 +1054,7 @@ type
|
|||||||
LibrarySymbolName,
|
LibrarySymbolName,
|
||||||
LibraryExpr : TPasExpr; // e.g. external LibraryExpr name LibrarySymbolName;
|
LibraryExpr : TPasExpr; // e.g. external LibraryExpr name LibrarySymbolName;
|
||||||
DispIDExpr : TPasExpr;
|
DispIDExpr : TPasExpr;
|
||||||
|
MessageExpr: TPasExpr;
|
||||||
AliasName : String;
|
AliasName : String;
|
||||||
ProcType : TPasProcedureType;
|
ProcType : TPasProcedureType;
|
||||||
Body : TProcedureBody;
|
Body : TProcedureBody;
|
||||||
@ -3398,6 +3399,7 @@ begin
|
|||||||
ReleaseAndNil(TPasElement(LibraryExpr){$IFDEF CheckPasTreeRefCount},'TPasProcedure.LibraryExpr'{$ENDIF});
|
ReleaseAndNil(TPasElement(LibraryExpr){$IFDEF CheckPasTreeRefCount},'TPasProcedure.LibraryExpr'{$ENDIF});
|
||||||
ReleaseAndNil(TPasElement(LibrarySymbolName){$IFDEF CheckPasTreeRefCount},'TPasProcedure.LibrarySymbolName'{$ENDIF});
|
ReleaseAndNil(TPasElement(LibrarySymbolName){$IFDEF CheckPasTreeRefCount},'TPasProcedure.LibrarySymbolName'{$ENDIF});
|
||||||
ReleaseAndNil(TPasElement(DispIDExpr){$IFDEF CheckPasTreeRefCount},'TPasProcedure.DispIDExpr'{$ENDIF});
|
ReleaseAndNil(TPasElement(DispIDExpr){$IFDEF CheckPasTreeRefCount},'TPasProcedure.DispIDExpr'{$ENDIF});
|
||||||
|
ReleaseAndNil(TPasElement(MessageExpr){$IFDEF CheckPasTreeRefCount},'TPasProcedure.MessageExpr'{$ENDIF});
|
||||||
ReleaseAndNil(TPasElement(ProcType){$IFDEF CheckPasTreeRefCount},'TPasProcedure.ProcType'{$ENDIF});
|
ReleaseAndNil(TPasElement(ProcType){$IFDEF CheckPasTreeRefCount},'TPasProcedure.ProcType'{$ENDIF});
|
||||||
ReleaseAndNil(TPasElement(Body){$IFDEF CheckPasTreeRefCount},'TPasProcedure.Body'{$ENDIF});
|
ReleaseAndNil(TPasElement(Body){$IFDEF CheckPasTreeRefCount},'TPasProcedure.Body'{$ENDIF});
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
@ -4472,6 +4474,7 @@ begin
|
|||||||
ForEachChildCall(aMethodCall,Arg,PublicName,false);
|
ForEachChildCall(aMethodCall,Arg,PublicName,false);
|
||||||
ForEachChildCall(aMethodCall,Arg,LibraryExpr,false);
|
ForEachChildCall(aMethodCall,Arg,LibraryExpr,false);
|
||||||
ForEachChildCall(aMethodCall,Arg,LibrarySymbolName,false);
|
ForEachChildCall(aMethodCall,Arg,LibrarySymbolName,false);
|
||||||
|
ForEachChildCall(aMethodCall,Arg,MessageExpr,false);
|
||||||
ForEachChildCall(aMethodCall,Arg,Body,false);
|
ForEachChildCall(aMethodCall,Arg,Body,false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -4866,21 +4866,24 @@ begin
|
|||||||
end;
|
end;
|
||||||
pmMessage:
|
pmMessage:
|
||||||
begin
|
begin
|
||||||
Repeat
|
NextToken;
|
||||||
NextToken;
|
E:=DoParseExpression(Parent);
|
||||||
If CurToken<>tkSemicolon then
|
TPasProcedure(Parent).MessageExpr:=E;
|
||||||
begin
|
if E is TPrimitiveExpr then
|
||||||
if Parent is TPasProcedure then
|
begin
|
||||||
TPasProcedure(Parent).MessageName:=CurtokenString;
|
TPasProcedure(Parent).MessageName:=TPrimitiveExpr(E).Value;
|
||||||
If (CurToken=tkString) and (Parent is TPasProcedure) then
|
case E.Kind of
|
||||||
TPasProcedure(Parent).Messagetype:=pmtString;
|
pekNumber, pekUnary: TPasProcedure(Parent).Messagetype:=pmtInteger;
|
||||||
end;
|
pekString: TPasProcedure(Parent).Messagetype:=pmtString;
|
||||||
until CurToken = tkSemicolon;
|
end;
|
||||||
UngetToken;
|
end;
|
||||||
|
if CurToken = tkSemicolon then
|
||||||
|
UngetToken;
|
||||||
end;
|
end;
|
||||||
pmDispID:
|
pmDispID:
|
||||||
begin
|
begin
|
||||||
TPasProcedure(Parent).DispIDExpr:=DoParseExpression(Parent,Nil);
|
NextToken;
|
||||||
|
TPasProcedure(Parent).DispIDExpr:=DoParseExpression(Parent);
|
||||||
if CurToken = tkSemicolon then
|
if CurToken = tkSemicolon then
|
||||||
UngetToken;
|
UngetToken;
|
||||||
end;
|
end;
|
||||||
|
@ -620,6 +620,8 @@ type
|
|||||||
Procedure TestClass_EnumeratorFunc;
|
Procedure TestClass_EnumeratorFunc;
|
||||||
Procedure TestClass_ForInPropertyStaticArray;
|
Procedure TestClass_ForInPropertyStaticArray;
|
||||||
Procedure TestClass_TypeAlias;
|
Procedure TestClass_TypeAlias;
|
||||||
|
Procedure TestClass_Message;
|
||||||
|
Procedure TestClass_Message_MissingParamFail;
|
||||||
|
|
||||||
// published
|
// published
|
||||||
Procedure TestClass_PublishedClassVarFail;
|
Procedure TestClass_PublishedClassVarFail;
|
||||||
@ -11118,6 +11120,42 @@ begin
|
|||||||
ParseProgram;
|
ParseProgram;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolver.TestClass_Message;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'const',
|
||||||
|
' FlyId = 2;',
|
||||||
|
' RunStr = ''Fast'';',
|
||||||
|
'type',
|
||||||
|
' TObject = class',
|
||||||
|
' procedure Fly(var msg); message 3+FlyId;',
|
||||||
|
' procedure Run(var msg); virtual; abstract; message ''prefix''+RunStr;',
|
||||||
|
' end;',
|
||||||
|
'procedure TObject.Fly(var msg);',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
ParseProgram;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestResolver.TestClass_Message_MissingParamFail;
|
||||||
|
begin
|
||||||
|
StartProgram(false);
|
||||||
|
Add([
|
||||||
|
'type',
|
||||||
|
' TObject = class',
|
||||||
|
' procedure Fly; message 3;',
|
||||||
|
' end;',
|
||||||
|
'procedure TObject.Fly;',
|
||||||
|
'begin',
|
||||||
|
'end;',
|
||||||
|
'begin',
|
||||||
|
'']);
|
||||||
|
CheckResolverException(sMessageHandlersInvalidParams,nMessageHandlersInvalidParams);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TTestResolver.TestClass_PublishedClassVarFail;
|
procedure TTestResolver.TestClass_PublishedClassVarFail;
|
||||||
begin
|
begin
|
||||||
StartProgram(false);
|
StartProgram(false);
|
||||||
|
Loading…
Reference in New Issue
Block a user