mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-04-04 17:08:44 +00:00
allow deprecation of classes/structs, deprecate Dictionary
This commit is contained in:
parent
35c44c7e21
commit
93c8af32ca
5 changed files with 67 additions and 19 deletions
|
@ -111,6 +111,8 @@ public:
|
|||
bool SizeKnown = true;
|
||||
|
||||
bool TypeInternal = false;
|
||||
bool TypeDeprecated = false; // mVersion is deprecation version, not minimum version
|
||||
FString mDeprecationMessage;
|
||||
|
||||
PType * LocalType = nullptr;
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ static void SetNodeLine(ZCC_TreeNode *name, int line)
|
|||
ZCC_Identifier *Replaces;
|
||||
ZCC_Identifier *Sealed;
|
||||
VersionInfo Version;
|
||||
FString *DeprecationMessage;
|
||||
};
|
||||
|
||||
struct StateOpts {
|
||||
|
@ -232,6 +233,7 @@ class_head(X) ::= EXTEND CLASS(T) IDENTIFIER(A).
|
|||
head->Version = {0, 0};
|
||||
head->Type = nullptr;
|
||||
head->Symbol = nullptr;
|
||||
head->DeprecationMessage = nullptr;
|
||||
X = head;
|
||||
}
|
||||
|
||||
|
@ -247,6 +249,7 @@ class_head(X) ::= CLASS(T) IDENTIFIER(A) class_ancestry(B) class_flags(C).
|
|||
head->Version = C.Version;
|
||||
head->Type = nullptr;
|
||||
head->Symbol = nullptr;
|
||||
head->DeprecationMessage = C.DeprecationMessage;
|
||||
X = head;
|
||||
}
|
||||
|
||||
|
@ -255,15 +258,24 @@ class_ancestry(X) ::= . { X = NULL; }
|
|||
class_ancestry(X) ::= COLON dottable_id(A). { X = A; /*X-overwrites-A*/ }
|
||||
|
||||
%type class_flags{ClassFlagsBlock}
|
||||
class_flags(X) ::= . { X.Flags = 0; X.Replaces = NULL; X.Version = {0,0}; X.Sealed = NULL; }
|
||||
class_flags(X) ::= class_flags(A) ABSTRACT. { X.Flags = A.Flags | ZCC_Abstract; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
|
||||
class_flags(X) ::= class_flags(A) FINAL. { X.Flags = A.Flags | ZCC_Final; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed;}
|
||||
class_flags(X) ::= class_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
|
||||
class_flags(X) ::= class_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
|
||||
class_flags(X) ::= class_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; }
|
||||
class_flags(X) ::= class_flags(A) REPLACES dottable_id(B). { X.Flags = A.Flags; X.Replaces = B; X.Version = A.Version; X.Sealed = A.Sealed; }
|
||||
class_flags(X) ::= class_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Replaces = A.Replaces; X.Version = C.String->GetChars(); X.Sealed = A.Sealed; }
|
||||
class_flags(X) ::= class_flags(A) SEALED LPAREN states_opt(B) RPAREN. { X.Flags = A.Flags | ZCC_Sealed; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = B; }
|
||||
class_flags(X) ::= . { X.Flags = 0; X.Replaces = NULL; X.Version = {0,0}; X.Sealed = NULL; X.DeprecationMessage = NULL; }
|
||||
class_flags(X) ::= class_flags(A) ABSTRACT. { X.Flags = A.Flags | ZCC_Abstract; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
class_flags(X) ::= class_flags(A) FINAL. { X.Flags = A.Flags | ZCC_Final; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
class_flags(X) ::= class_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
class_flags(X) ::= class_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
class_flags(X) ::= class_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = A.Sealed; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
class_flags(X) ::= class_flags(A) REPLACES dottable_id(B). { X.Flags = A.Flags; X.Replaces = B; X.Version = A.Version; X.Sealed = A.Sealed; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
class_flags(X) ::= class_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Replaces = A.Replaces; X.Version = C.String->GetChars(); X.Sealed = A.Sealed; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
class_flags(X) ::= class_flags(A) SEALED LPAREN states_opt(B) RPAREN. { X.Flags = A.Flags | ZCC_Sealed; X.Replaces = A.Replaces; X.Version = A.Version; X.Sealed = B; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
|
||||
class_flags(X) ::= class_flags(A) DEPRECATED LPAREN STRCONST(C) opt_deprecation_message(D) RPAREN.
|
||||
{
|
||||
X.Flags = A.Flags | ZCC_Deprecated;
|
||||
X.Replaces = A.Replaces;
|
||||
X.Version = C.String->GetChars();
|
||||
X.Sealed = A.Sealed;
|
||||
X.DeprecationMessage = D.String;
|
||||
}
|
||||
|
||||
/*----- Dottable Identifier -----*/
|
||||
// This can be either a single identifier or two identifiers connected by a .
|
||||
|
@ -412,6 +424,7 @@ struct_def(X) ::= STRUCT(T) IDENTIFIER(A) struct_flags(S) LBRACE opt_struct_body
|
|||
def->Symbol = nullptr;
|
||||
def->Version = S.Version;
|
||||
def->Flags = S.Flags;
|
||||
def->DeprecationMessage = S.DeprecationMessage;
|
||||
X = def;
|
||||
}
|
||||
|
||||
|
@ -422,18 +435,27 @@ struct_def(X) ::= EXTEND STRUCT(T) IDENTIFIER(A) LBRACE opt_struct_body(B) RBRAC
|
|||
def->Body = B;
|
||||
def->Type = nullptr;
|
||||
def->Symbol = nullptr;
|
||||
def->Version = {0, 0};
|
||||
def->Flags = ZCC_Extension;
|
||||
def->DeprecationMessage = nullptr;
|
||||
X = def;
|
||||
}
|
||||
|
||||
%type struct_flags{ClassFlagsBlock}
|
||||
struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; }
|
||||
struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; }
|
||||
struct_flags(X) ::= struct_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; }
|
||||
struct_flags(X) ::= struct_flags(A) CLEARSCOPE. { X.Flags = A.Flags | ZCC_ClearScope; }
|
||||
struct_flags(X) ::= struct_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; }
|
||||
struct_flags(X) ::= struct_flags(A) INTERNAL. { X.Flags = A.Flags | ZCC_Internal; }
|
||||
struct_flags(X) ::= struct_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Version = C.String->GetChars(); }
|
||||
struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; X.DeprecationMessage = NULL; }
|
||||
struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
struct_flags(X) ::= struct_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
struct_flags(X) ::= struct_flags(A) CLEARSCOPE. { X.Flags = A.Flags | ZCC_ClearScope; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
struct_flags(X) ::= struct_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
struct_flags(X) ::= struct_flags(A) INTERNAL. { X.Flags = A.Flags | ZCC_Internal; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
|
||||
struct_flags(X) ::= struct_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Version = C.String->GetChars(); X.DeprecationMessage = A.DeprecationMessage; }
|
||||
|
||||
struct_flags(X) ::= struct_flags(A) DEPRECATED LPAREN STRCONST(C) opt_deprecation_message(D) RPAREN.
|
||||
{
|
||||
X.Flags = A.Flags | ZCC_Deprecated;
|
||||
X.Version = C.String->GetChars();
|
||||
X.DeprecationMessage = D.String;
|
||||
}
|
||||
|
||||
opt_struct_body(X) ::= . { X = NULL; }
|
||||
opt_struct_body(X) ::= struct_body(X).
|
||||
|
|
|
@ -751,6 +751,13 @@ void ZCCCompiler::CreateStructTypes()
|
|||
s->strct->Type->mVersion = s->strct->Version;
|
||||
}
|
||||
|
||||
if (s->strct->Flags & ZCC_Deprecated)
|
||||
{
|
||||
s->strct->Type->mVersion = s->strct->Version;
|
||||
s->strct->Type->TypeDeprecated = true;
|
||||
s->strct->Type->mDeprecationMessage = s->strct->DeprecationMessage ? *s->strct->DeprecationMessage : "";
|
||||
}
|
||||
|
||||
if (s->strct->Flags & ZCC_Internal)
|
||||
{
|
||||
s->strct->Type->TypeInternal = true;
|
||||
|
@ -919,6 +926,13 @@ void ZCCCompiler::CreateClassTypes()
|
|||
{
|
||||
c->Type()->mVersion = c->cls->Version;
|
||||
}
|
||||
|
||||
if (c->cls->Flags & ZCC_Deprecated)
|
||||
{
|
||||
c->Type()->mVersion = c->cls->Version;
|
||||
c->Type()->TypeDeprecated = true;
|
||||
c->Type()->mDeprecationMessage = c->cls->DeprecationMessage ? *c->cls->DeprecationMessage : "";
|
||||
}
|
||||
|
||||
|
||||
if (c->cls->Flags & ZCC_Final)
|
||||
|
@ -2177,7 +2191,16 @@ PType *ZCCCompiler::ResolveUserType(PType *outertype, ZCC_BasicType *type, ZCC_I
|
|||
if (sym != nullptr && sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
|
||||
{
|
||||
auto ptype = static_cast<PSymbolType *>(sym)->Type;
|
||||
if (ptype->mVersion > mVersion)
|
||||
|
||||
if (ptype->TypeDeprecated)
|
||||
{
|
||||
if(ptype->mVersion <= mVersion && !outertype->TypeDeprecated && fileSystem.GetFileContainer(Lump) > 0)
|
||||
{
|
||||
Warn(type, "Type %s is deprecated since ZScript version %d.%d.%d%s%s",
|
||||
FName(type->UserType->Id).GetChars(), mVersion.major, mVersion.minor, mVersion.revision, ptype->mDeprecationMessage.IsEmpty() ? "" : ": ", ptype->mDeprecationMessage.GetChars());
|
||||
}
|
||||
}
|
||||
else if (ptype->mVersion > mVersion)
|
||||
{
|
||||
Error(type, "Type %s not accessible to ZScript version %d.%d.%d", FName(type->UserType->Id).GetChars(), mVersion.major, mVersion.minor, mVersion.revision);
|
||||
return TypeError;
|
||||
|
|
|
@ -243,6 +243,7 @@ struct ZCC_Struct : ZCC_NamedNode
|
|||
ZCC_TreeNode *Body;
|
||||
PContainerType *Type;
|
||||
VersionInfo Version;
|
||||
FString *DeprecationMessage;
|
||||
};
|
||||
|
||||
struct ZCC_Property : ZCC_NamedNode
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*
|
||||
* @note keys are case-sensitive.
|
||||
*/
|
||||
class Dictionary
|
||||
class Dictionary deprecated("4.15", "Use Map<String, String> instead")
|
||||
{
|
||||
native static Dictionary Create();
|
||||
|
||||
|
@ -38,7 +38,7 @@ class Dictionary
|
|||
* DictionaryIterator is not serializable. To make DictionaryIterator a class
|
||||
* member, use `transient` keyword.
|
||||
*/
|
||||
class DictionaryIterator
|
||||
class DictionaryIterator deprecated("4.15", "Use Map<String, String> instead")
|
||||
{
|
||||
native static DictionaryIterator Create(Dictionary dict);
|
||||
|
||||
|
|
Loading…
Reference in a new issue