mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-16 06:26:25 +02:00
- msg*: found a message to reuse
- pdecobj.pas: removed a check whether a class (helper) tries to inherit from a class helper, because now single_type handles this - pexpr.pas: * prohibit type casts to class helpers (note: this might be needed for ObjC categories as well) * class helper references may only be used when inheriting from them (needs to be checked for ObjC categories as well) - ptype.pas: * single_type: extend check against categories for class helpers * read_named_type: extend check against categories for class helpers - symbase.pas: add a method that adds symbol table flags recursivly to a stack of symtables (it stops updating the symtables once a symtable already has that flag or it's a global-/staticsymtable) - symdef.pas: adjusted the constructor of tobjectdef to use the new method for adding flags git-svn-id: branches/svenbarth/classhelpers@16889 -
This commit is contained in:
parent
e19bcfae38
commit
7cc7826343
@ -368,7 +368,7 @@ scanner_w_illegal_warn_identifier=02087_W_Illegal identifier "$1" for $WARN dire
|
||||
#
|
||||
# Parser
|
||||
#
|
||||
# 03308 is the last used one
|
||||
# 03307 is the last used one
|
||||
#
|
||||
% \section{Parser messages}
|
||||
% This section lists all parser messages. The parser takes care of the
|
||||
@ -1264,9 +1264,12 @@ parser_e_objc_message_name_changed=03275_E_Message name "$1" in inherited class
|
||||
parser_e_no_objc_unique=03276_E_It is not yet possible to make unique copies of Objective-C types
|
||||
% Duplicating an Objective-C type using \var{type x = type y;} is not yet supported. You may be able to
|
||||
% obtain the desired effect using \var{type x = objcclass(y) end;} instead.
|
||||
parser_e_no_category_as_types=03277_E_Objective-C categories cannot be used as types
|
||||
% It is not possible to declare a variable as an instance of an Objective-C category. A
|
||||
% category adds methods to the scope of an existing class, but does not define a type by itself.
|
||||
parser_e_no_category_as_types=03277_E_Objective-C categories and Object Pascal class helpers cannot be used as types
|
||||
% It is not possible to declare a variable as an instance of an Objective-C
|
||||
% category or an Object Pascal class helper. A category/class helper adds
|
||||
% methods to the scope of an existing class, but does not define a type by
|
||||
% itself. An exception of this rule is when inheriting an Object Pascal class
|
||||
% helper from another class helper.
|
||||
parser_e_no_category_override=03278_E_Categories do not override, but replace methods. Use "reintroduce" instead.
|
||||
parser_e_must_use_reintroduce_objc=03279_E_Replaced methods can only be reintroduced in Objective-C, add "reintroduce" (replaced method defined in $1).
|
||||
parser_h_should_use_reintroduce_objc=03280_H_Replaced methods can only be reintroduced in Objective-C, add "reintroduce" (replaced method defined in $1).
|
||||
@ -1370,10 +1373,7 @@ parser_e_classhelper_id_expected=03305_E_Class helper identifier expected
|
||||
parser_e_classhelper_must_extend_subclass=03306_E_Derived class helper must extend a subclass of the class extended by the parent class helper
|
||||
% When a class helper inherits from another class helper the extended class must
|
||||
% extend either the same class as the parent class helper or a subclass of it
|
||||
parser_e_classhelper_not_allowed_here=03307_E_A class helper is not allowed here
|
||||
% A class helper can only be referenced when inheriting from it. All other uses
|
||||
% (like variable type, field type, parameter type, with clause) are disallowed.
|
||||
parser_e_not_allowed_in_classhelper=03308_E_"$1" is not allowed in class helpers
|
||||
parser_e_not_allowed_in_classhelper=03307_E_"$1" is not allowed in class helpers
|
||||
% Some directives and specifiers like "virtual", "dynamic", "published" aren't
|
||||
% allowed inside class helpers in mode ObjFPC (they are ignored in mode Delphi).
|
||||
% \end{description}
|
||||
|
@ -395,8 +395,7 @@ const
|
||||
parser_e_cant_use_type_parameters_here=03304;
|
||||
parser_e_classhelper_id_expected=03305;
|
||||
parser_e_classhelper_must_extend_subclass=03306;
|
||||
parser_e_classhelper_not_allowed_here=03307;
|
||||
parser_e_not_allowed_in_classhelper=03308;
|
||||
parser_e_not_allowed_in_classhelper=03307;
|
||||
type_e_mismatch=04000;
|
||||
type_e_incompatible_types=04001;
|
||||
type_e_not_equal_types=04002;
|
||||
@ -886,9 +885,9 @@ const
|
||||
option_info=11024;
|
||||
option_help_pages=11025;
|
||||
|
||||
MsgTxtSize = 58949;
|
||||
MsgTxtSize = 58938;
|
||||
|
||||
MsgIdxMax : array[1..20] of longint=(
|
||||
24,88,309,99,84,54,111,22,202,63,
|
||||
24,88,308,99,84,54,111,22,202,63,
|
||||
49,20,1,1,1,1,1,1,1,1
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -482,29 +482,23 @@ implementation
|
||||
isn't allowed }
|
||||
case current_objectdef.objecttype of
|
||||
odt_class:
|
||||
if is_objectpascal_classhelper(childof) then
|
||||
{ a class helper is not allowed as parent or extended
|
||||
class
|
||||
}
|
||||
Message(parser_e_classhelper_not_allowed_here)
|
||||
if not(is_class(childof)) then
|
||||
begin
|
||||
if is_interface(childof) then
|
||||
begin
|
||||
{ we insert the interface after the child
|
||||
is set, see below
|
||||
}
|
||||
intfchildof:=childof;
|
||||
childof:=class_tobject;
|
||||
end
|
||||
else
|
||||
Message(parser_e_mix_of_classes_and_objects);
|
||||
end
|
||||
else
|
||||
if not(is_class(childof)) then
|
||||
begin
|
||||
if is_interface(childof) then
|
||||
begin
|
||||
{ we insert the interface after the child
|
||||
is set, see below
|
||||
}
|
||||
intfchildof:=childof;
|
||||
childof:=class_tobject;
|
||||
end
|
||||
else
|
||||
Message(parser_e_mix_of_classes_and_objects);
|
||||
end
|
||||
else
|
||||
if (oo_is_sealed in childof.objectoptions) and
|
||||
not is_objectpascal_classhelper(current_structdef) then
|
||||
Message1(parser_e_sealed_descendant,childof.typename);
|
||||
if (oo_is_sealed in childof.objectoptions) and
|
||||
not is_objectpascal_classhelper(current_structdef) then
|
||||
Message1(parser_e_sealed_descendant,childof.typename);
|
||||
odt_interfacecorba,
|
||||
odt_interfacecom:
|
||||
begin
|
||||
|
@ -1488,7 +1488,12 @@ implementation
|
||||
begin
|
||||
p1:=comp_expr(true,false);
|
||||
consume(_RKLAMMER);
|
||||
p1:=ctypeconvnode.create_explicit(p1,hdef);
|
||||
{ type casts to class helpers aren't allowed }
|
||||
if is_objectpascal_classhelper(hdef) then
|
||||
Message(parser_e_no_category_as_types)
|
||||
{ recovery by not creating a conversion node }
|
||||
else
|
||||
p1:=ctypeconvnode.create_explicit(p1,hdef);
|
||||
end
|
||||
else { not LKLAMMER }
|
||||
if (token=_POINT) and
|
||||
@ -1534,6 +1539,12 @@ implementation
|
||||
if is_class(hdef) or
|
||||
is_objcclass(hdef) then
|
||||
begin
|
||||
if is_objectpascal_classhelper(hdef) then
|
||||
begin
|
||||
Message(parser_e_no_category_as_types);
|
||||
{ for recovery we use the extended class }
|
||||
hdef:=tobjectdef(hdef).childof;
|
||||
end;
|
||||
if getaddr and (token=_POINT) then
|
||||
begin
|
||||
consume(_POINT);
|
||||
|
@ -568,7 +568,7 @@ implementation
|
||||
Message(parser_e_no_generics_as_types);
|
||||
def:=generrordef;
|
||||
end
|
||||
else if is_objccategory(def) then
|
||||
else if is_classhelper(def) then
|
||||
begin
|
||||
Message(parser_e_no_category_as_types);
|
||||
def:=generrordef
|
||||
@ -1035,7 +1035,7 @@ implementation
|
||||
Message(parser_e_no_generics_as_types);
|
||||
def:=generrordef;
|
||||
end
|
||||
else if is_objccategory(def) then
|
||||
else if is_classhelper(def) then
|
||||
begin
|
||||
Message(parser_e_no_category_as_types);
|
||||
def:=generrordef
|
||||
|
@ -114,6 +114,9 @@ interface
|
||||
procedure insertdef(def:TDefEntry);virtual;
|
||||
procedure deletedef(def:TDefEntry);
|
||||
function iscurrentunit:boolean;virtual;
|
||||
{ includes the flag in this symtable and all parent symtables; if
|
||||
it's already set the flag is not set again }
|
||||
procedure includeoption(option:tsymtableoption);
|
||||
end;
|
||||
|
||||
psymtablestackitem = ^TSymtablestackitem;
|
||||
@ -263,6 +266,26 @@ implementation
|
||||
result:=false;
|
||||
end;
|
||||
|
||||
procedure TSymtable.includeoption(option: tsymtableoption);
|
||||
var
|
||||
st: tsymtable;
|
||||
begin
|
||||
if option in tableoptions then
|
||||
exit;
|
||||
include(tableoptions,option);
|
||||
{ iterative approach should be faster than recursion based on calls }
|
||||
st:=self;
|
||||
while assigned(st.defowner) do
|
||||
begin
|
||||
st:=st.defowner.owner;
|
||||
{ the flag is already set, so by definition it is set in the
|
||||
owning symtables as well }
|
||||
if option in st.tableoptions then
|
||||
break;
|
||||
include(st.tableoptions,option);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TSymtable.clear;
|
||||
var
|
||||
|
@ -4148,24 +4148,13 @@ implementation
|
||||
***************************************************************************}
|
||||
|
||||
constructor tobjectdef.create(ot:tobjecttyp;const n:string;c:tobjectdef);
|
||||
|
||||
procedure update_unit_symtable_options;
|
||||
var
|
||||
st: tsymtable;
|
||||
begin
|
||||
st:=owner;
|
||||
while not(st.symtabletype in [globalsymtable,staticsymtable]) do
|
||||
st:=st.defowner.owner;
|
||||
if objecttype in [odt_classhelper,odt_objccategory] then
|
||||
include(st.tableoptions,sto_has_classhelper);
|
||||
end;
|
||||
|
||||
begin
|
||||
inherited create(n,objectdef);
|
||||
fcurrent_dispid:=0;
|
||||
objecttype:=ot;
|
||||
childof:=nil;
|
||||
update_unit_symtable_options;
|
||||
if objecttype in [odt_classhelper] then
|
||||
owner.includeoption(sto_has_classhelper);
|
||||
symtable:=tObjectSymtable.create(self,n,current_settings.packrecords);
|
||||
{ create space for vmt !! }
|
||||
vmtentries:=TFPList.Create;
|
||||
|
Loading…
Reference in New Issue
Block a user