mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-05 14:06:12 +02:00
* automatically generate versions of inherited virtual class methods that
call through to the parent method in case they are not overridden in the child class, because otherwise the dynamic dispatch fails (looking up a class method only checks that particular class, since they are never virtual in Java and hence not inherited either) git-svn-id: branches/jvmbackend@18715 -
This commit is contained in:
parent
57c7e21d8f
commit
ad871b6acd
@ -1429,7 +1429,7 @@ implementation
|
||||
we obviously cannot add constructors to those) }
|
||||
if is_javaclass(current_structdef) then
|
||||
begin
|
||||
add_missing_parent_constructors_intf(tobjectdef(current_structdef),vis_none);
|
||||
add_missing_parent_constructors_intf(tobjectdef(current_structdef),true,vis_none);
|
||||
{$ifdef jvm}
|
||||
maybe_add_public_default_java_constructor(tobjectdef(current_structdef));
|
||||
jvm_wrap_virtual_class_methods(tobjectdef(current_structdef));
|
||||
|
@ -357,7 +357,7 @@ implementation
|
||||
begin
|
||||
{ insert "private constructor(string,int,int)" that calls inherited and
|
||||
initialises the FPC value field }
|
||||
add_missing_parent_constructors_intf(enumclass,vis_strictprivate);
|
||||
add_missing_parent_constructors_intf(enumclass,false,vis_strictprivate);
|
||||
end;
|
||||
{ add instance method to get the enum's value as declared in FPC }
|
||||
if not str_parse_method_dec('function FPCOrdinal: longint;',potype_function,false,enumclass,pd) then
|
||||
@ -463,7 +463,7 @@ implementation
|
||||
symtablestack.push(pvclass.symtable);
|
||||
|
||||
{ inherit constructor and keep public }
|
||||
add_missing_parent_constructors_intf(pvclass,vis_public);
|
||||
add_missing_parent_constructors_intf(pvclass,true,vis_public);
|
||||
|
||||
{ add a method to call the procvar using unwrapped arguments, which
|
||||
then wraps them and calls through to JLRMethod.invoke }
|
||||
|
@ -74,8 +74,9 @@ interface
|
||||
|
||||
{ in the JVM, constructors are not automatically inherited (so you can hide
|
||||
them). To emulate the Pascal behaviour, we have to automatically add
|
||||
all parent constructors to the current class as well.}
|
||||
procedure add_missing_parent_constructors_intf(obj: tobjectdef; forcevis: tvisibility);
|
||||
all parent constructors to the current class as well. We also have to do
|
||||
the same for the (emulated) virtual class methods }
|
||||
procedure add_missing_parent_constructors_intf(obj: tobjectdef; addvirtclassmeth: boolean; forcevis: tvisibility);
|
||||
|
||||
{ goes through all defs in st to add implementations for synthetic methods
|
||||
added earlier }
|
||||
@ -245,7 +246,7 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure add_missing_parent_constructors_intf(obj: tobjectdef; forcevis: tvisibility);
|
||||
procedure add_missing_parent_constructors_intf(obj: tobjectdef; addvirtclassmeth: boolean; forcevis: tvisibility);
|
||||
var
|
||||
parent: tobjectdef;
|
||||
def: tdef;
|
||||
@ -264,7 +265,9 @@ implementation
|
||||
begin
|
||||
def:=tdef(tobjectsymtable(parent.symtable).deflist[i]);
|
||||
if (def.typ<>procdef) or
|
||||
(tprocdef(def).proctypeoption<>potype_constructor) or
|
||||
((tprocdef(def).proctypeoption<>potype_constructor) and
|
||||
(not addvirtclassmeth or
|
||||
not([po_classmethod,po_virtualmethod]<=tprocdef(def).procoptions))) or
|
||||
not is_visible_for_object(tprocdef(def),obj) then
|
||||
continue;
|
||||
parentpd:=tprocdef(def);
|
||||
@ -273,12 +276,12 @@ implementation
|
||||
search parents too) }
|
||||
if searchsym_in_record(obj,parentpd.procsym.name,srsym,srsymtable) then
|
||||
begin
|
||||
{ there's a symbol with the same name, is it a constructor
|
||||
with the same parameters? }
|
||||
{ there's a symbol with the same name, is it a routine of the
|
||||
same type with the same parameters? }
|
||||
if srsym.typ=procsym then
|
||||
begin
|
||||
childpd:=tprocsym(srsym).find_procdef_bytype_and_para(
|
||||
potype_constructor,parentpd.paras,nil,
|
||||
tprocdef(def).proctypeoption,parentpd.paras,nil,
|
||||
[cpo_ignorehidden,cpo_ignoreuniv,cpo_openequalisexact]);
|
||||
if assigned(childpd) then
|
||||
continue;
|
||||
@ -287,6 +290,13 @@ implementation
|
||||
{ if we get here, we did not find it in the current objectdef ->
|
||||
add }
|
||||
childpd:=tprocdef(parentpd.getcopy);
|
||||
{ get rid of the import name for inherited virtual class methods,
|
||||
it has to be regenerated rather than amended }
|
||||
if [po_classmethod,po_virtualmethod]<=childpd.procoptions then
|
||||
begin
|
||||
stringdispose(childpd.import_name);
|
||||
exclude(childpd.procoptions,po_has_importname);
|
||||
end;
|
||||
if forcevis<>vis_none then
|
||||
childpd.visibility:=forcevis;
|
||||
if po_virtualmethod in childpd.procoptions then
|
||||
|
Loading…
Reference in New Issue
Block a user