mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 00:09:26 +02:00
* refactor is_visible_for_object
git-svn-id: trunk@12152 -
This commit is contained in:
parent
552e5fc66f
commit
36cad44923
@ -1781,7 +1781,7 @@ implementation
|
|||||||
(
|
(
|
||||||
ignorevisibility or
|
ignorevisibility or
|
||||||
(pd.owner.symtabletype<>objectsymtable) or
|
(pd.owner.symtabletype<>objectsymtable) or
|
||||||
pd.is_visible_for_object(contextobjdef,nil)
|
is_visible_for_object(pd,contextobjdef)
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
{ don't add duplicates, only compare visible parameters for the user }
|
{ don't add duplicates, only compare visible parameters for the user }
|
||||||
|
@ -210,7 +210,7 @@ implementation
|
|||||||
new(procdefcoll);
|
new(procdefcoll);
|
||||||
procdefcoll^.data:=pd;
|
procdefcoll^.data:=pd;
|
||||||
procdefcoll^.hidden:=false;
|
procdefcoll^.hidden:=false;
|
||||||
procdefcoll^.visible:=pd.is_visible_for_object(_class,nil);
|
procdefcoll^.visible:=is_visible_for_object(pd,_class);
|
||||||
VMTSymEntry.ProcdefList.Add(procdefcoll);
|
VMTSymEntry.ProcdefList.Add(procdefcoll);
|
||||||
|
|
||||||
{ Register virtual method and give it a number }
|
{ Register virtual method and give it a number }
|
||||||
@ -252,7 +252,7 @@ implementation
|
|||||||
procdefs, because they can be reused in the next class.
|
procdefs, because they can be reused in the next class.
|
||||||
The check to skip the invisible methods that are in the
|
The check to skip the invisible methods that are in the
|
||||||
list is futher down in the code }
|
list is futher down in the code }
|
||||||
is_visible:=pd.is_visible_for_object(_class,nil);
|
is_visible:=is_visible_for_object(pd,_class);
|
||||||
{ Load other values for easier readability }
|
{ Load other values for easier readability }
|
||||||
hasoverloads:=(tprocsym(pd.procsym).ProcdefList.Count>1);
|
hasoverloads:=(tprocsym(pd.procsym).ProcdefList.Count>1);
|
||||||
pdoverload:=(po_overload in pd.procoptions);
|
pdoverload:=(po_overload in pd.procoptions);
|
||||||
|
@ -430,7 +430,7 @@ implementation
|
|||||||
{ search the constructor also in the symbol tables of
|
{ search the constructor also in the symbol tables of
|
||||||
the parents }
|
the parents }
|
||||||
afterassignment:=false;
|
afterassignment:=false;
|
||||||
searchsym_in_class(classh,nil,pattern,srsym,srsymtable);
|
searchsym_in_class(classh,classh,pattern,srsym,srsymtable);
|
||||||
consume(_ID);
|
consume(_ID);
|
||||||
do_member_read(classh,false,srsym,p1,again,[cnf_new_call]);
|
do_member_read(classh,false,srsym,p1,again,[cnf_new_call]);
|
||||||
{ we need to know which procedure is called }
|
{ we need to know which procedure is called }
|
||||||
|
@ -487,7 +487,6 @@ interface
|
|||||||
function cplusplusmangledname : string;
|
function cplusplusmangledname : string;
|
||||||
function is_methodpointer:boolean;override;
|
function is_methodpointer:boolean;override;
|
||||||
function is_addressonly:boolean;override;
|
function is_addressonly:boolean;override;
|
||||||
function is_visible_for_object(currobjdef,contextobjdef:tobjectdef):boolean;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ single linked list of overloaded procs }
|
{ single linked list of overloaded procs }
|
||||||
@ -3177,60 +3176,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tprocdef.is_visible_for_object(currobjdef,contextobjdef:tobjectdef):boolean;
|
|
||||||
var
|
|
||||||
contextst : TSymtable;
|
|
||||||
begin
|
|
||||||
result:=false;
|
|
||||||
|
|
||||||
{ Support passing a context in which module we are to find protected members }
|
|
||||||
if assigned(contextobjdef) then
|
|
||||||
contextst:=contextobjdef.owner
|
|
||||||
else
|
|
||||||
contextst:=nil;
|
|
||||||
|
|
||||||
{ private symbols are allowed when we are in the same
|
|
||||||
module as they are defined }
|
|
||||||
if (visibility=vis_private) and
|
|
||||||
(owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
||||||
not(owner.defowner.owner.iscurrentunit or (owner.defowner.owner=contextst)) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
if (visibility=vis_strictprivate) then
|
|
||||||
begin
|
|
||||||
result:=currobjdef=tobjectdef(owner.defowner);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (visibility=vis_strictprotected) then
|
|
||||||
begin
|
|
||||||
result:=assigned(currobjdef) and
|
|
||||||
currobjdef.is_related(tobjectdef(owner.defowner));
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ protected symbols are visible in the module that defines them and
|
|
||||||
also visible to related objects. The related object must be defined
|
|
||||||
in the current module }
|
|
||||||
if (visibility=vis_protected) and
|
|
||||||
(
|
|
||||||
(
|
|
||||||
(owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
||||||
not((owner.defowner.owner.iscurrentunit) or (owner.defowner.owner=contextst))
|
|
||||||
) and
|
|
||||||
not(
|
|
||||||
assigned(currobjdef) and
|
|
||||||
(currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
||||||
(currobjdef.owner.iscurrentunit) and
|
|
||||||
currobjdef.is_related(tobjectdef(owner.defowner))
|
|
||||||
)
|
|
||||||
) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
result:=true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function tprocdef.GetSymtable(t:tGetSymtable):TSymtable;
|
function tprocdef.GetSymtable(t:tGetSymtable):TSymtable;
|
||||||
begin
|
begin
|
||||||
case t of
|
case t of
|
||||||
|
@ -99,9 +99,6 @@ interface
|
|||||||
function find_procdef_bypara(para:TFPObjectList;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
|
function find_procdef_bypara(para:TFPObjectList;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
|
||||||
function find_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
|
function find_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
|
||||||
function find_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
|
function find_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
|
||||||
{ currobjdef is the object def to assume, this is necessary for protected and
|
|
||||||
private, context is the object def we're really in, this is for the strict stuff }
|
|
||||||
function is_visible_for_object(currobjdef:tdef;context:tdef):boolean;override;
|
|
||||||
property ProcdefList:TFPObjectList read FProcdefList;
|
property ProcdefList:TFPObjectList read FProcdefList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -752,27 +749,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tprocsym.is_visible_for_object(currobjdef:tdef;context:tdef):boolean;
|
|
||||||
var
|
|
||||||
i : longint;
|
|
||||||
pd : tprocdef;
|
|
||||||
begin
|
|
||||||
{ This procsym is visible, when there is at least
|
|
||||||
one of the procdefs visible }
|
|
||||||
result:=false;
|
|
||||||
for i:=0 to ProcdefList.Count-1 do
|
|
||||||
begin
|
|
||||||
pd:=tprocdef(ProcdefList[i]);
|
|
||||||
if (pd.owner=owner) and
|
|
||||||
pd.is_visible_for_object(tobjectdef(currobjdef),tobjectdef(context)) then
|
|
||||||
begin
|
|
||||||
result:=true;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
TERRORSYM
|
TERRORSYM
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
@ -190,6 +190,9 @@ interface
|
|||||||
|
|
||||||
{*** Search ***}
|
{*** Search ***}
|
||||||
procedure addsymref(sym:tsym);
|
procedure addsymref(sym:tsym);
|
||||||
|
function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tobjectdef):boolean;
|
||||||
|
function is_visible_for_object(pd:tprocdef;contextobjdef:tobjectdef):boolean;
|
||||||
|
function is_visible_for_object(sym:tsym;contextobjdef:tobjectdef):boolean;
|
||||||
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_type(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_in_module(pm:pointer;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
@ -1094,8 +1097,9 @@ implementation
|
|||||||
hsym:=search_class_member(tobjectdef(defowner),hashedid.id);
|
hsym:=search_class_member(tobjectdef(defowner),hashedid.id);
|
||||||
if assigned(hsym) and
|
if assigned(hsym) and
|
||||||
(
|
(
|
||||||
(not(m_delphi in current_settings.modeswitches) and
|
(
|
||||||
tsym(hsym).is_visible_for_object(tobjectdef(defowner),tobjectdef(defowner))
|
not(m_delphi in current_settings.modeswitches) and
|
||||||
|
is_visible_for_object(hsym,tobjectdef(defowner))
|
||||||
) or
|
) or
|
||||||
(
|
(
|
||||||
{ In Delphi, you can repeat members of a parent class. You can't }
|
{ In Delphi, you can repeat members of a parent class. You can't }
|
||||||
@ -1537,11 +1541,95 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function is_visible_for_object(symst:tsymtable;symvisibility:tvisibility;contextobjdef:tobjectdef):boolean;
|
||||||
|
var
|
||||||
|
symownerdef : tobjectdef;
|
||||||
|
begin
|
||||||
|
result:=false;
|
||||||
|
|
||||||
|
{ Get objdectdef owner of the symtable for the is_related checks }
|
||||||
|
if not assigned(symst) or
|
||||||
|
(symst.symtabletype<>objectsymtable) then
|
||||||
|
internalerror(200810285);
|
||||||
|
symownerdef:=tobjectdef(symst.defowner);
|
||||||
|
case symvisibility of
|
||||||
|
vis_private :
|
||||||
|
begin
|
||||||
|
{ private symbols are allowed when we are in the same
|
||||||
|
module as they are defined }
|
||||||
|
result:=(symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
||||||
|
(symownerdef.owner.iscurrentunit);
|
||||||
|
end;
|
||||||
|
vis_strictprivate :
|
||||||
|
begin
|
||||||
|
result:=assigned(current_objectdef) and
|
||||||
|
(current_objectdef=symownerdef);
|
||||||
|
end;
|
||||||
|
vis_strictprotected :
|
||||||
|
begin
|
||||||
|
result:=assigned(current_objectdef) and
|
||||||
|
current_objectdef.is_related(symownerdef);
|
||||||
|
end;
|
||||||
|
vis_protected :
|
||||||
|
begin
|
||||||
|
{ protected symbols are visible in the module that defines them and
|
||||||
|
also visible to related objects. The related object must be defined
|
||||||
|
in the current module }
|
||||||
|
result:=(
|
||||||
|
(
|
||||||
|
(symownerdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
||||||
|
(symownerdef.owner.iscurrentunit)
|
||||||
|
) or
|
||||||
|
(
|
||||||
|
assigned(contextobjdef) and
|
||||||
|
(contextobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
||||||
|
(contextobjdef.owner.iscurrentunit) and
|
||||||
|
contextobjdef.is_related(symownerdef)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
vis_public,
|
||||||
|
vis_published :
|
||||||
|
result:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function is_visible_for_object(pd:tprocdef;contextobjdef:tobjectdef):boolean;
|
||||||
|
begin
|
||||||
|
result:=is_visible_for_object(pd.owner,pd.visibility,contextobjdef);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function is_visible_for_object(sym:tsym;contextobjdef:tobjectdef):boolean;
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
pd : tprocdef;
|
||||||
|
begin
|
||||||
|
if sym.typ=procsym then
|
||||||
|
begin
|
||||||
|
{ A procsym is visible, when there is at least one of the procdefs visible }
|
||||||
|
result:=false;
|
||||||
|
for i:=0 to tprocsym(sym).ProcdefList.Count-1 do
|
||||||
|
begin
|
||||||
|
pd:=tprocdef(tprocsym(sym).ProcdefList[i]);
|
||||||
|
if (pd.owner=sym.owner) and
|
||||||
|
is_visible_for_object(pd,contextobjdef) then
|
||||||
|
begin
|
||||||
|
result:=true;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result:=is_visible_for_object(sym.owner,sym.visibility,contextobjdef);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym(const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
var
|
var
|
||||||
hashedid : THashedIDString;
|
hashedid : THashedIDString;
|
||||||
topclass : tobjectdef;
|
contextobjdef : tobjectdef;
|
||||||
context : tobjectdef;
|
|
||||||
stackitem : psymtablestackitem;
|
stackitem : psymtablestackitem;
|
||||||
begin
|
begin
|
||||||
result:=false;
|
result:=false;
|
||||||
@ -1553,7 +1641,6 @@ implementation
|
|||||||
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
||||||
if assigned(srsym) then
|
if assigned(srsym) then
|
||||||
begin
|
begin
|
||||||
topclass:=nil;
|
|
||||||
{ use the class from withsymtable only when it is
|
{ use the class from withsymtable only when it is
|
||||||
defined in this unit }
|
defined in this unit }
|
||||||
if (srsymtable.symtabletype=withsymtable) and
|
if (srsymtable.symtabletype=withsymtable) and
|
||||||
@ -1561,11 +1648,11 @@ implementation
|
|||||||
(srsymtable.defowner.typ=objectdef) and
|
(srsymtable.defowner.typ=objectdef) and
|
||||||
(srsymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
(srsymtable.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
||||||
(srsymtable.defowner.owner.iscurrentunit) then
|
(srsymtable.defowner.owner.iscurrentunit) then
|
||||||
topclass:=tobjectdef(srsymtable.defowner)
|
contextobjdef:=tobjectdef(srsymtable.defowner)
|
||||||
else
|
else
|
||||||
topclass:=current_objectdef;
|
contextobjdef:=current_objectdef;
|
||||||
context:=current_objectdef;
|
if (srsym.owner.symtabletype<>objectsymtable) or
|
||||||
if tsym(srsym).is_visible_for_object(topclass,context) then
|
is_visible_for_object(srsym,contextobjdef) then
|
||||||
begin
|
begin
|
||||||
{ we need to know if a procedure references symbols
|
{ we need to know if a procedure references symbols
|
||||||
in the static symtable, because then it can't be
|
in the static symtable, because then it can't be
|
||||||
@ -1614,8 +1701,10 @@ implementation
|
|||||||
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
||||||
if assigned(srsym) and
|
if assigned(srsym) and
|
||||||
not(srsym.typ in [fieldvarsym,paravarsym]) and
|
not(srsym.typ in [fieldvarsym,paravarsym]) and
|
||||||
(not assigned(current_objectdef) or
|
(
|
||||||
tsym(srsym).is_visible_for_object(current_objectdef,current_objectdef)) then
|
(srsym.owner.symtabletype<>objectsymtable) or
|
||||||
|
is_visible_for_object(srsym,current_objectdef)
|
||||||
|
) then
|
||||||
begin
|
begin
|
||||||
{ we need to know if a procedure references symbols
|
{ we need to know if a procedure references symbols
|
||||||
in the static symtable, because then it can't be
|
in the static symtable, because then it can't be
|
||||||
@ -1674,8 +1763,14 @@ implementation
|
|||||||
|
|
||||||
function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
function searchsym_in_class(classh,contextclassh:tobjectdef;const s : TIDString;out srsym:tsym;out srsymtable:TSymtable):boolean;
|
||||||
var
|
var
|
||||||
hashedid : THashedIDString;
|
hashedid : THashedIDString;
|
||||||
begin
|
begin
|
||||||
|
{ The contextclassh is used for visibility. The classh must be equal to
|
||||||
|
or be a parent of contextclassh. E.g. for inherited searches the classh is the
|
||||||
|
parent. }
|
||||||
|
if assigned(classh) and
|
||||||
|
not contextclassh.is_related(classh) then
|
||||||
|
internalerror(200811161);
|
||||||
result:=false;
|
result:=false;
|
||||||
hashedid.id:=s;
|
hashedid.id:=s;
|
||||||
while assigned(classh) do
|
while assigned(classh) do
|
||||||
@ -1683,7 +1778,7 @@ implementation
|
|||||||
srsymtable:=classh.symtable;
|
srsymtable:=classh.symtable;
|
||||||
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
srsym:=tsym(srsymtable.FindWithHash(hashedid));
|
||||||
if assigned(srsym) and
|
if assigned(srsym) and
|
||||||
tsym(srsym).is_visible_for_object(contextclassh,current_objectdef) then
|
is_visible_for_object(srsym,contextclassh) then
|
||||||
begin
|
begin
|
||||||
addsymref(srsym);
|
addsymref(srsym);
|
||||||
result:=true;
|
result:=true;
|
||||||
|
@ -106,11 +106,6 @@ interface
|
|||||||
function mangledname:string; virtual;
|
function mangledname:string; virtual;
|
||||||
procedure buildderef;virtual;
|
procedure buildderef;virtual;
|
||||||
procedure deref;virtual;
|
procedure deref;virtual;
|
||||||
{ currobjdef is the object def to assume, this is necessary for protected and
|
|
||||||
private,
|
|
||||||
context is the object def we're really in, this is for the strict stuff
|
|
||||||
}
|
|
||||||
function is_visible_for_object(currobjdef:tdef;context : tdef):boolean;virtual;
|
|
||||||
procedure ChangeOwner(st:TSymtable);
|
procedure ChangeOwner(st:TSymtable);
|
||||||
procedure IncRefCount;
|
procedure IncRefCount;
|
||||||
procedure IncRefCountBy(AValue : longint);
|
procedure IncRefCountBy(AValue : longint);
|
||||||
@ -388,58 +383,8 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tsym.is_visible_for_object(currobjdef:Tdef;context : tdef):boolean;
|
|
||||||
begin
|
|
||||||
is_visible_for_object:=false;
|
|
||||||
|
|
||||||
{ private symbols are allowed when we are in the same
|
|
||||||
module as they are defined }
|
|
||||||
if (visibility=vis_private) and
|
|
||||||
assigned(owner.defowner) and
|
|
||||||
(owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
||||||
(not owner.defowner.owner.iscurrentunit) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
if (visibility=vis_strictprivate) then
|
|
||||||
begin
|
|
||||||
result:=assigned(currobjdef) and
|
|
||||||
(context=tdef(owner.defowner));
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (visibility=vis_strictprotected) then
|
|
||||||
begin
|
|
||||||
result:=assigned(context) and
|
|
||||||
context.is_related(tdef(owner.defowner));
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ protected symbols are visible in the module that defines them and
|
|
||||||
also visible to related objects }
|
|
||||||
if (visibility=vis_protected) and
|
|
||||||
(
|
|
||||||
(
|
|
||||||
assigned(owner.defowner) and
|
|
||||||
(owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
||||||
(not owner.defowner.owner.iscurrentunit)
|
|
||||||
) and
|
|
||||||
not(
|
|
||||||
assigned(currobjdef) and
|
|
||||||
(currobjdef.owner.symtabletype in [globalsymtable,staticsymtable]) and
|
|
||||||
(currobjdef.owner.iscurrentunit) and
|
|
||||||
currobjdef.is_related(tdef(owner.defowner))
|
|
||||||
)
|
|
||||||
) then
|
|
||||||
exit;
|
|
||||||
|
|
||||||
is_visible_for_object:=true;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
procedure tsym.ChangeOwner(st:TSymtable);
|
procedure tsym.ChangeOwner(st:TSymtable);
|
||||||
begin
|
begin
|
||||||
// if assigned(Owner) then
|
|
||||||
// Owner.SymList.List.List^[i].Data:=nil;
|
|
||||||
Owner:=st;
|
Owner:=st;
|
||||||
inherited ChangeOwner(Owner.SymList);
|
inherited ChangeOwner(Owner.SymList);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user