mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-06 05:58:33 +02:00
* nflw.pas: search for enumerators in helpers for records as well
* pdecobj.pas: - parse_object_members: in record helpers class methods need to be declared as "static" like in records - object_dec: - allow "published" in helpers as well - disallow inheritance for record helpers in mode Delphi (and remove the forward declaration flag in that case) * pdecsub.pas: pd_abstract: "abstract" isn't allowed in either mode * pexpr.pas: multiple corrections because of "inherited" and records - allow "inherited" for "record helpers" (except for mode Delphi) - load the symbol from the correct class (I hope...) - give a more precise error message if "inherited" is used in records * ptype.pas: I forgot to adjust the "(bit)packed record" case * symtable.pas: - searchsym_in_helper: "result" was not initialized (and identation fix) - search_last_objectpascal_helper: - don't search if there are no helpers (useful for projects that does not contain helpers like the compiler itself) - don't search if the type to search helpers for is defined locally - don't search if the type is a anonymous record - search_struct_member: search for symbols in helpers as well - msg*: * correct the message for "parser_e_not_allowed_in_helper" * add message "parser_e_inherited_not_in_record" which is used to tell that the use of "inherited" is not allowed in records and (in mode Delphi) record helpers git-svn-id: branches/svenbarth/classhelpers@17239 -
This commit is contained in:
parent
c0a0ec9962
commit
a944be69a6
@ -368,7 +368,7 @@ scanner_w_illegal_warn_identifier=02087_W_Illegal identifier "$1" for $WARN dire
|
|||||||
#
|
#
|
||||||
# Parser
|
# Parser
|
||||||
#
|
#
|
||||||
# 03306 is the last used one
|
# 03307 is the last used one
|
||||||
#
|
#
|
||||||
% \section{Parser messages}
|
% \section{Parser messages}
|
||||||
% This section lists all parser messages. The parser takes care of the
|
% This section lists all parser messages. The parser takes care of the
|
||||||
@ -1368,12 +1368,16 @@ parser_e_at_least_one_argument_must_be_of_type=03303_E_Either the result or at l
|
|||||||
parser_e_cant_use_type_parameters_here=03304_E_Type parameters may require initialization/finalization - can't be used in variant records
|
parser_e_cant_use_type_parameters_here=03304_E_Type parameters may require initialization/finalization - can't be used in variant records
|
||||||
% Type parameters may be specialized with types which (e.g. \var{ansistring}) need initialization/finalization
|
% Type parameters may be specialized with types which (e.g. \var{ansistring}) need initialization/finalization
|
||||||
% code which is implicitly generated by the compiler.
|
% code which is implicitly generated by the compiler.
|
||||||
parser_e_not_allowed_in_helper=03305_E_"$1" is not allowed in helpers
|
parser_e_not_allowed_in_helper=03305_E_"$1" is not allowed in helper types
|
||||||
% Some directives and specifiers like "virtual", "dynamic", "override" aren't
|
% Some directives and specifiers like "virtual", "dynamic", "override" aren't
|
||||||
% allowed inside class helpers in mode ObjFPC (they are ignored in mode Delphi),
|
% allowed inside helper types in mode ObjFPC (they are ignored in mode Delphi),
|
||||||
% because they have no meaning within helpers.
|
% because they have no meaning within helpers. Also "abstract" isn't allowed in
|
||||||
|
% either mode.
|
||||||
parser_e_no_class_constructor_in_helpers=03306_E_Class constructors aren't allowed in helpers
|
parser_e_no_class_constructor_in_helpers=03306_E_Class constructors aren't allowed in helpers
|
||||||
% Class constructor declarations aren't allowed in helpers.
|
% Class constructor declarations aren't allowed in helpers.
|
||||||
|
parser_e_inherited_not_in_record=03307_E_The use of "inherited" is not allowed in a record
|
||||||
|
% As records don't suppport inheritance the use of "inherited" is prohibited for
|
||||||
|
% these as well as for record helpers (in mode "Delphi" only).
|
||||||
% \end{description}
|
% \end{description}
|
||||||
# Type Checking
|
# Type Checking
|
||||||
#
|
#
|
||||||
|
@ -395,6 +395,7 @@ const
|
|||||||
parser_e_cant_use_type_parameters_here=03304;
|
parser_e_cant_use_type_parameters_here=03304;
|
||||||
parser_e_not_allowed_in_helper=03305;
|
parser_e_not_allowed_in_helper=03305;
|
||||||
parser_e_no_class_constructor_in_helpers=03306;
|
parser_e_no_class_constructor_in_helpers=03306;
|
||||||
|
parser_e_inherited_not_in_record=03307;
|
||||||
type_e_mismatch=04000;
|
type_e_mismatch=04000;
|
||||||
type_e_incompatible_types=04001;
|
type_e_incompatible_types=04001;
|
||||||
type_e_not_equal_types=04002;
|
type_e_not_equal_types=04002;
|
||||||
@ -888,9 +889,9 @@ const
|
|||||||
option_info=11024;
|
option_info=11024;
|
||||||
option_help_pages=11025;
|
option_help_pages=11025;
|
||||||
|
|
||||||
MsgTxtSize = 59014;
|
MsgTxtSize = 59095;
|
||||||
|
|
||||||
MsgIdxMax : array[1..20] of longint=(
|
MsgIdxMax : array[1..20] of longint=(
|
||||||
24,88,307,103,84,54,111,22,202,63,
|
24,88,308,103,84,54,111,22,202,63,
|
||||||
49,20,1,1,1,1,1,1,1,1
|
49,20,1,1,1,1,1,1,1,1
|
||||||
);
|
);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -863,10 +863,8 @@ implementation
|
|||||||
// if there is no operator then search for class/object enumerator method
|
// if there is no operator then search for class/object enumerator method
|
||||||
if (pd=nil) and (expr.resultdef.typ in [objectdef,recorddef]) then
|
if (pd=nil) and (expr.resultdef.typ in [objectdef,recorddef]) then
|
||||||
begin
|
begin
|
||||||
{ first search using the class helper hierarchy if it's a
|
{ first search using the helper hierarchy }
|
||||||
class }
|
if search_last_objectpascal_helper(tabstractrecorddef(expr.resultdef),nil,helperdef) then
|
||||||
if (expr.resultdef.typ=objectdef) and
|
|
||||||
search_last_objectpascal_helper(tobjectdef(expr.resultdef),nil,helperdef) then
|
|
||||||
repeat
|
repeat
|
||||||
pd:=helperdef.search_enumerator_get;
|
pd:=helperdef.search_enumerator_get;
|
||||||
helperdef:=helperdef.childof;
|
helperdef:=helperdef.childof;
|
||||||
|
@ -915,6 +915,12 @@ implementation
|
|||||||
if (m_mac in current_settings.modeswitches) then
|
if (m_mac in current_settings.modeswitches) then
|
||||||
include(pd.procoptions,po_virtualmethod);
|
include(pd.procoptions,po_virtualmethod);
|
||||||
|
|
||||||
|
{ for record helpers only static class methods are allowed }
|
||||||
|
if is_objectpascal_helper(current_structdef) and
|
||||||
|
is_record(current_objectdef.extendeddef) and
|
||||||
|
is_classdef and not (po_staticmethod in pd.procoptions) then
|
||||||
|
MessagePos(pd.fileinfo, parser_e_class_methods_only_static_in_records);
|
||||||
|
|
||||||
handle_calling_convention(pd);
|
handle_calling_convention(pd);
|
||||||
|
|
||||||
{ add definition to procsym }
|
{ add definition to procsym }
|
||||||
@ -1139,7 +1145,7 @@ implementation
|
|||||||
{ set published flag in $M+ mode, it can also be inherited and will
|
{ set published flag in $M+ mode, it can also be inherited and will
|
||||||
be added when the parent class set with tobjectdef.set_parent (PFV) }
|
be added when the parent class set with tobjectdef.set_parent (PFV) }
|
||||||
if (cs_generate_rtti in current_settings.localswitches) and
|
if (cs_generate_rtti in current_settings.localswitches) and
|
||||||
(current_objectdef.objecttype in [odt_interfacecom,odt_class]) then
|
(current_objectdef.objecttype in [odt_interfacecom,odt_class,odt_helper]) then
|
||||||
include(current_structdef.objectoptions,oo_can_have_published);
|
include(current_structdef.objectoptions,oo_can_have_published);
|
||||||
|
|
||||||
{ Objective-C objectdefs can be "formal definitions", in which case
|
{ Objective-C objectdefs can be "formal definitions", in which case
|
||||||
@ -1179,7 +1185,15 @@ implementation
|
|||||||
parse_generic:=(df_generic in current_structdef.defoptions);
|
parse_generic:=(df_generic in current_structdef.defoptions);
|
||||||
|
|
||||||
{ parse list of parent classes }
|
{ parse list of parent classes }
|
||||||
parse_parent_classes;
|
{ for record helpers in mode Delphi this is not allowed }
|
||||||
|
if not (is_objectpascal_helper(current_objectdef) and
|
||||||
|
(m_delphi in current_settings.modeswitches) and
|
||||||
|
(helpertype=ht_record)) then
|
||||||
|
parse_parent_classes
|
||||||
|
else
|
||||||
|
{ remove forward flag, is resolved (this is normally done inside
|
||||||
|
parse_parent_classes) }
|
||||||
|
exclude(current_structdef.objectoptions,oo_is_forward);
|
||||||
|
|
||||||
{ parse extended type for helpers }
|
{ parse extended type for helpers }
|
||||||
if is_objectpascal_helper(current_structdef) then
|
if is_objectpascal_helper(current_structdef) then
|
||||||
|
@ -1628,8 +1628,7 @@ procedure pd_abstract(pd:tabstractprocdef);
|
|||||||
begin
|
begin
|
||||||
if pd.typ<>procdef then
|
if pd.typ<>procdef then
|
||||||
internalerror(200304269);
|
internalerror(200304269);
|
||||||
if is_objectpascal_helper(tprocdef(pd).struct) and
|
if is_objectpascal_helper(tprocdef(pd).struct) then
|
||||||
(m_objfpc in current_settings.modeswitches) then
|
|
||||||
Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_ABSTRACT].str);
|
Message1(parser_e_not_allowed_in_helper, arraytokeninfo[_ABSTRACT].str);
|
||||||
if assigned(tprocdef(pd).struct) and
|
if assigned(tprocdef(pd).struct) and
|
||||||
(oo_is_sealed in tprocdef(pd).struct.objectoptions) then
|
(oo_is_sealed in tprocdef(pd).struct.objectoptions) then
|
||||||
|
@ -2361,16 +2361,13 @@ implementation
|
|||||||
assigned(current_structdef) and
|
assigned(current_structdef) and
|
||||||
(current_structdef.typ=objectdef) then
|
(current_structdef.typ=objectdef) then
|
||||||
begin
|
begin
|
||||||
{ In Object Pascal helpers "inherited" always calls a
|
{ for record helpers in mode Delphi "inherited" is not
|
||||||
method of the extended class }
|
allowed }
|
||||||
if is_objectpascal_helper(current_structdef) then
|
if is_objectpascal_helper(current_structdef) and
|
||||||
begin
|
(m_delphi in current_settings.modeswitches) and
|
||||||
if not is_class(tobjectdef(current_structdef).extendeddef) then
|
is_record(tobjectdef(current_structdef).extendeddef) then
|
||||||
Internalerror(2011021701);
|
Message(parser_e_inherited_not_in_record);
|
||||||
hclassdef:=tobjectdef(tobjectdef(current_structdef).extendeddef);
|
hclassdef:=tobjectdef(current_structdef).childof;
|
||||||
end
|
|
||||||
else
|
|
||||||
hclassdef:=tobjectdef(current_structdef).childof;
|
|
||||||
{ Objective-C categories *replace* methods in the class
|
{ Objective-C categories *replace* methods in the class
|
||||||
they extend, or add methods to it. So calling an
|
they extend, or add methods to it. So calling an
|
||||||
inherited method always calls the method inherited from
|
inherited method always calls the method inherited from
|
||||||
@ -2420,7 +2417,25 @@ implementation
|
|||||||
case srsym.typ of
|
case srsym.typ of
|
||||||
procsym:
|
procsym:
|
||||||
begin
|
begin
|
||||||
hdef:=hclassdef;
|
if is_objectpascal_helper(current_structdef) then
|
||||||
|
begin
|
||||||
|
{ for a helper load the procdef either from the
|
||||||
|
extended type, from the parent helper or from
|
||||||
|
the extended type of the parent helper
|
||||||
|
depending on the def the found symbol belongs
|
||||||
|
to }
|
||||||
|
if (srsym.Owner.defowner.typ=objectdef) and
|
||||||
|
is_objectpascal_helper(tobjectdef(srsym.Owner.defowner)) then
|
||||||
|
if current_structdef.is_related(tdef(srsym.Owner.defowner)) and
|
||||||
|
assigned(tobjectdef(current_structdef).childof) then
|
||||||
|
hdef:=tobjectdef(current_structdef).childof
|
||||||
|
else
|
||||||
|
hdef:=tobjectdef(srsym.Owner.defowner).extendeddef
|
||||||
|
else
|
||||||
|
hdef:=tdef(srsym.Owner.defowner);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
hdef:=hclassdef;
|
||||||
if (po_classmethod in current_procinfo.procdef.procoptions) or
|
if (po_classmethod in current_procinfo.procdef.procoptions) or
|
||||||
(po_staticmethod in current_procinfo.procdef.procoptions) then
|
(po_staticmethod in current_procinfo.procdef.procoptions) then
|
||||||
hdef:=tclassrefdef.create(hdef);
|
hdef:=tclassrefdef.create(hdef);
|
||||||
@ -2469,9 +2484,14 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
Message(parser_e_generic_methods_only_in_methods);
|
{ in case of records we use a more clear error message }
|
||||||
again:=false;
|
if assigned(current_structdef) and
|
||||||
p1:=cerrornode.create;
|
(current_structdef.typ=recorddef) then
|
||||||
|
Message(parser_e_inherited_not_in_record)
|
||||||
|
else
|
||||||
|
Message(parser_e_generic_methods_only_in_methods);
|
||||||
|
again:=false;
|
||||||
|
p1:=cerrornode.create;
|
||||||
end;
|
end;
|
||||||
postfixoperators(p1,again);
|
postfixoperators(p1,again);
|
||||||
end;
|
end;
|
||||||
|
@ -1524,8 +1524,10 @@ implementation
|
|||||||
consume(_OBJECT);
|
consume(_OBJECT);
|
||||||
def:=object_dec(odt_object,name,genericdef,genericlist,nil,ht_none);
|
def:=object_dec(odt_object,name,genericdef,genericlist,nil,ht_none);
|
||||||
end;
|
end;
|
||||||
else
|
else begin
|
||||||
|
consume(_RECORD);
|
||||||
def:=record_dec(name,genericdef,genericlist);
|
def:=record_dec(name,genericdef,genericlist);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
current_settings.packrecords:=oldpackrecords;
|
current_settings.packrecords:=oldpackrecords;
|
||||||
end;
|
end;
|
||||||
|
@ -2348,6 +2348,7 @@ implementation
|
|||||||
hashedid : THashedIDString;
|
hashedid : THashedIDString;
|
||||||
parentclassh : tobjectdef;
|
parentclassh : tobjectdef;
|
||||||
begin
|
begin
|
||||||
|
result:=false;
|
||||||
if not is_objectpascal_helper(classh) then
|
if not is_objectpascal_helper(classh) then
|
||||||
Internalerror(2011030101);
|
Internalerror(2011030101);
|
||||||
hashedid.id:=s;
|
hashedid.id:=s;
|
||||||
@ -2395,10 +2396,10 @@ implementation
|
|||||||
end;
|
end;
|
||||||
parentclassh:=parentclassh.childof;
|
parentclassh:=parentclassh.childof;
|
||||||
end;
|
end;
|
||||||
if is_class(classh.extendeddef) then
|
if is_class(classh.extendeddef) then
|
||||||
{ now search in the parents of the extended class (with helpers!) }
|
{ now search in the parents of the extended class (with helpers!) }
|
||||||
result:=searchsym_in_class(tobjectdef(classh.extendeddef).childof,contextclassh,s,srsym,srsymtable,true);
|
result:=searchsym_in_class(tobjectdef(classh.extendeddef).childof,contextclassh,s,srsym,srsymtable,true);
|
||||||
{ addsymref is already called by searchsym_in_class }
|
{ addsymref is already called by searchsym_in_class }
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function search_specific_assignment_operator(assignment_type:ttoken;from_def,to_def:Tdef):Tprocdef;
|
function search_specific_assignment_operator(assignment_type:ttoken;from_def,to_def:Tdef):Tprocdef;
|
||||||
@ -2543,10 +2544,11 @@ implementation
|
|||||||
s: string;
|
s: string;
|
||||||
list: TFPObjectList;
|
list: TFPObjectList;
|
||||||
i: integer;
|
i: integer;
|
||||||
|
st: tsymtable;
|
||||||
{$endif}
|
{$endif}
|
||||||
begin
|
begin
|
||||||
{$ifdef useoldsearch}
|
|
||||||
result:=false;
|
result:=false;
|
||||||
|
{$ifdef useoldsearch}
|
||||||
stackitem:=symtablestack.stack;
|
stackitem:=symtablestack.stack;
|
||||||
while assigned(stackitem) do
|
while assigned(stackitem) do
|
||||||
begin
|
begin
|
||||||
@ -2574,7 +2576,21 @@ implementation
|
|||||||
stackitem:=stackitem^.next;
|
stackitem:=stackitem^.next;
|
||||||
end;
|
end;
|
||||||
{$else}
|
{$else}
|
||||||
result:=false;
|
{ when there are no helpers active currently then we don't need to do
|
||||||
|
anything }
|
||||||
|
if current_module.extendeddefs.count=0 then
|
||||||
|
exit;
|
||||||
|
{ no helpers for anonymous types }
|
||||||
|
if not assigned(pd.objrealname) or (pd.objrealname^='') then
|
||||||
|
exit;
|
||||||
|
{ if pd is defined inside a procedure we must not use make_mangledname
|
||||||
|
(as a helper may not be defined in a procedure this is no problem...)}
|
||||||
|
st:=pd.owner;
|
||||||
|
while st.symtabletype in [objectsymtable,recordsymtable] do
|
||||||
|
st:=st.defowner.owner;
|
||||||
|
if st.symtabletype=localsymtable then
|
||||||
|
exit;
|
||||||
|
{ the mangled name is used as the key for tmodule.extendeddefs }
|
||||||
s:=make_mangledname('',pd.symtable,'');
|
s:=make_mangledname('',pd.symtable,'');
|
||||||
list:=TFPObjectList(current_module.extendeddefs.Find(s));
|
list:=TFPObjectList(current_module.extendeddefs.Find(s));
|
||||||
if assigned(list) and (list.count>0) then
|
if assigned(list) and (list.count>0) then
|
||||||
@ -2775,6 +2791,8 @@ implementation
|
|||||||
{ in case this is a formal objcclass, first find the real definition }
|
{ in case this is a formal objcclass, first find the real definition }
|
||||||
if (oo_is_formal in pd.objectoptions) then
|
if (oo_is_formal in pd.objectoptions) then
|
||||||
pd:=find_real_objcclass_definition(tobjectdef(pd),true);
|
pd:=find_real_objcclass_definition(tobjectdef(pd),true);
|
||||||
|
if search_objectpascal_helper(pd, pd, s, result, srsymtable) then
|
||||||
|
exit;
|
||||||
hashedid.id:=s;
|
hashedid.id:=s;
|
||||||
orgpd:=pd;
|
orgpd:=pd;
|
||||||
while assigned(pd) do
|
while assigned(pd) do
|
||||||
|
Loading…
Reference in New Issue
Block a user