mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-14 04:30:48 +02:00
Initial support of parametrized dispinterface properties:
* When parsing dispinterface properties, pass parameter/index nodes to translate_disp_call() instead of dropping them. * Distinguish property getters from regular method calls and generate appropriate call descriptors. git-svn-id: trunk@16753 -
This commit is contained in:
parent
97e700bbcc
commit
3a23a3ebe0
@ -220,8 +220,14 @@ interface
|
|||||||
end;
|
end;
|
||||||
tcallparanodeclass = class of tcallparanode;
|
tcallparanodeclass = class of tcallparanode;
|
||||||
|
|
||||||
|
tdispcalltype = (
|
||||||
|
dct_method,
|
||||||
|
dct_propget,
|
||||||
|
dct_propput
|
||||||
|
);
|
||||||
|
|
||||||
function reverseparameters(p: tcallparanode): tcallparanode;
|
function reverseparameters(p: tcallparanode): tcallparanode;
|
||||||
function translate_disp_call(selfnode,parametersnode,putvalue : tnode;const methodname : ansistring;dispid : longint;resultdef : tdef) : tnode;
|
function translate_disp_call(selfnode,parametersnode: tnode; calltype: tdispcalltype; const methodname : ansistring;dispid : longint;resultdef : tdef) : tnode;
|
||||||
|
|
||||||
var
|
var
|
||||||
ccallnode : tcallnodeclass = tcallnode;
|
ccallnode : tcallnodeclass = tcallnode;
|
||||||
@ -273,7 +279,7 @@ implementation
|
|||||||
reverseparameters:=hp1;
|
reverseparameters:=hp1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function translate_disp_call(selfnode,parametersnode,putvalue : tnode; const methodname : ansistring;dispid : longint;resultdef : tdef) : tnode;
|
function translate_disp_call(selfnode,parametersnode: tnode; calltype: tdispcalltype; const methodname : ansistring;dispid : longint;resultdef : tdef) : tnode;
|
||||||
const
|
const
|
||||||
DISPATCH_METHOD = $1;
|
DISPATCH_METHOD = $1;
|
||||||
DISPATCH_PROPERTYGET = $2;
|
DISPATCH_PROPERTYGET = $2;
|
||||||
@ -281,8 +287,8 @@ implementation
|
|||||||
DISPATCH_PROPERTYPUTREF = $8;
|
DISPATCH_PROPERTYPUTREF = $8;
|
||||||
DISPATCH_CONSTRUCT = $4000;
|
DISPATCH_CONSTRUCT = $4000;
|
||||||
|
|
||||||
calltypes: array[Boolean] of byte = (
|
calltypes: array[tdispcalltype] of byte = (
|
||||||
DISPATCH_METHOD, DISPATCH_PROPERTYPUT
|
DISPATCH_METHOD, DISPATCH_PROPERTYGET, DISPATCH_PROPERTYPUT
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
statements : tstatementnode;
|
statements : tstatementnode;
|
||||||
@ -421,7 +427,7 @@ implementation
|
|||||||
calldescnode.appendbyte(restype);
|
calldescnode.appendbyte(restype);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
calldescnode.appendbyte(calltypes[assigned(putvalue)]);
|
calldescnode.appendbyte(calltypes[calltype]);
|
||||||
calldescnode.appendbyte(paracount);
|
calldescnode.appendbyte(paracount);
|
||||||
calldescnode.appendbyte(namedparacount);
|
calldescnode.appendbyte(namedparacount);
|
||||||
|
|
||||||
@ -2991,13 +2997,13 @@ implementation
|
|||||||
converted_result_data:=ctempcreatenode.create(procdefinition.returndef,sizeof(procdefinition.returndef),tt_persistent,true);
|
converted_result_data:=ctempcreatenode.create(procdefinition.returndef,sizeof(procdefinition.returndef),tt_persistent,true);
|
||||||
addstatement(statements,converted_result_data);
|
addstatement(statements,converted_result_data);
|
||||||
addstatement(statements,cassignmentnode.create(ctemprefnode.create(converted_result_data),
|
addstatement(statements,cassignmentnode.create(ctemprefnode.create(converted_result_data),
|
||||||
ctypeconvnode.create_internal(translate_disp_call(methodpointer,parameters,nil,'',tprocdef(procdefinition).dispid,procdefinition.returndef),
|
ctypeconvnode.create_internal(translate_disp_call(methodpointer,parameters,dct_method,'',tprocdef(procdefinition).dispid,procdefinition.returndef),
|
||||||
procdefinition.returndef)));
|
procdefinition.returndef)));
|
||||||
addstatement(statements,ctempdeletenode.create_normal_temp(converted_result_data));
|
addstatement(statements,ctempdeletenode.create_normal_temp(converted_result_data));
|
||||||
addstatement(statements,ctemprefnode.create(converted_result_data));
|
addstatement(statements,ctemprefnode.create(converted_result_data));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result:=translate_disp_call(methodpointer,parameters,nil,'',tprocdef(procdefinition).dispid,voidtype);
|
result:=translate_disp_call(methodpointer,parameters,dct_method,'',tprocdef(procdefinition).dispid,voidtype);
|
||||||
|
|
||||||
{ don't free reused nodes }
|
{ don't free reused nodes }
|
||||||
methodpointer:=nil;
|
methodpointer:=nil;
|
||||||
|
@ -1115,9 +1115,9 @@ implementation
|
|||||||
consume(_ASSIGNMENT);
|
consume(_ASSIGNMENT);
|
||||||
p2:=comp_expr(true,false);
|
p2:=comp_expr(true,false);
|
||||||
{ concat value parameter too }
|
{ concat value parameter too }
|
||||||
p2:=ccallparanode.create(p2,nil);
|
p2:=ccallparanode.create(p2,paras);
|
||||||
{ passing p3 here is only for information purposes }
|
paras:=nil;
|
||||||
p1:=translate_disp_call(p1,p2,p2,'',propsym.dispid,voidtype);
|
p1:=translate_disp_call(p1,p2,dct_propput,'',propsym.dispid,voidtype);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -1177,11 +1177,12 @@ implementation
|
|||||||
converted_result_data:=ctempcreatenode.create(propsym.propdef,sizeof(propsym.propdef),tt_persistent,true);
|
converted_result_data:=ctempcreatenode.create(propsym.propdef,sizeof(propsym.propdef),tt_persistent,true);
|
||||||
addstatement(statements,converted_result_data);
|
addstatement(statements,converted_result_data);
|
||||||
addstatement(statements,cassignmentnode.create(ctemprefnode.create(converted_result_data),
|
addstatement(statements,cassignmentnode.create(ctemprefnode.create(converted_result_data),
|
||||||
ctypeconvnode.create_internal(translate_disp_call(p1,nil,nil,'',propsym.dispid,propsym.propdef),
|
ctypeconvnode.create_internal(translate_disp_call(p1,paras,dct_propget,'',propsym.dispid,propsym.propdef),
|
||||||
propsym.propdef)));
|
propsym.propdef)));
|
||||||
addstatement(statements,ctempdeletenode.create_normal_temp(converted_result_data));
|
addstatement(statements,ctempdeletenode.create_normal_temp(converted_result_data));
|
||||||
addstatement(statements,ctemprefnode.create(converted_result_data));
|
addstatement(statements,ctemprefnode.create(converted_result_data));
|
||||||
p1:=p2;
|
p1:=p2;
|
||||||
|
paras:=nil;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -2141,16 +2142,15 @@ implementation
|
|||||||
p3:=comp_expr(true,false);
|
p3:=comp_expr(true,false);
|
||||||
{ concat value parameter too }
|
{ concat value parameter too }
|
||||||
p2:=ccallparanode.create(p3,p2);
|
p2:=ccallparanode.create(p3,p2);
|
||||||
{ passing p3 here is only for information purposes }
|
p1:=translate_disp_call(p1,p2,dct_propput,dispatchstring,0,voidtype);
|
||||||
p1:=translate_disp_call(p1,p2,p3,dispatchstring,0,voidtype);
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{ this is only an approximation
|
{ this is only an approximation
|
||||||
setting useresult if not necessary is only a waste of time, no more, no less (FK) }
|
setting useresult if not necessary is only a waste of time, no more, no less (FK) }
|
||||||
if afterassignment or in_args or (token<>_SEMICOLON) then
|
if afterassignment or in_args or (token<>_SEMICOLON) then
|
||||||
p1:=translate_disp_call(p1,p2,nil,dispatchstring,0,cvarianttype)
|
p1:=translate_disp_call(p1,p2,dct_method,dispatchstring,0,cvarianttype)
|
||||||
else
|
else
|
||||||
p1:=translate_disp_call(p1,p2,nil,dispatchstring,0,voidtype);
|
p1:=translate_disp_call(p1,p2,dct_method,dispatchstring,0,voidtype);
|
||||||
end
|
end
|
||||||
else { Error }
|
else { Error }
|
||||||
Consume(_ID);
|
Consume(_ID);
|
||||||
|
Loading…
Reference in New Issue
Block a user