44
44
#include " core/templates/hash_map.h"
45
45
#include " scene/main/node.h"
46
46
47
+ #ifdef TOOLS_ENABLED
48
+ #include " editor/editor_help.h"
49
+ #endif
50
+
47
51
#if defined(TOOLS_ENABLED) && !defined(DISABLE_DEPRECATED)
48
52
#define SUGGEST_GODOT4_RENAMES
49
53
#include " editor/renames_map_3_to_4.h"
@@ -1993,6 +1997,57 @@ void GDScriptAnalyzer::resolve_assignable(GDScriptParser::AssignableNode *p_assi
1993
1997
type = specified_type;
1994
1998
}
1995
1999
2000
+ #if TOOLS_ENABLED
2001
+ DocTools *dd = EditorHelp::get_doc_data ();
2002
+ bool is_deprecated = false ;
2003
+ String new_value_type = " value" ;
2004
+ String value_name = type.native_type ;
2005
+ switch (type.kind ) {
2006
+ case GDScriptParser::DataType::Kind::BUILTIN: // No built-in datatypes are deprecated.
2007
+ break ;
2008
+ case GDScriptParser::DataType::Kind::NATIVE:
2009
+ is_deprecated = dd && dd->class_list .has (type.native_type ) && dd->class_list [type.native_type ].is_deprecated ;
2010
+ new_value_type = " class" ;
2011
+ break ;
2012
+ case GDScriptParser::DataType::Kind::SCRIPT: {
2013
+ StringName class_name = type.script_type ->get_doc_class_name ();
2014
+ is_deprecated = dd && dd->class_list .has (class_name) && dd->class_list [class_name].is_deprecated ;
2015
+ new_value_type = " class" ;
2016
+ break ;
2017
+ }
2018
+ case GDScriptParser::DataType::Kind::CLASS:
2019
+ is_deprecated = type.class_type ->doc_data .is_deprecated ;
2020
+ new_value_type = " class" ;
2021
+
2022
+ // TODO: Not recognizing the autoload name as a class type
2023
+ // var my_var: MyAutoload # <--- not getting this name
2024
+ if (type.class_type && type.class_type ->identifier ) {
2025
+ value_name = type.class_type ->identifier ->name ;
2026
+ } else {
2027
+ value_name = " " ;
2028
+ }
2029
+ break ;
2030
+ case GDScriptParser::DataType::Kind::ENUM: {
2031
+ StringName enum_type = type.enum_type ; // Something like MyEnum.
2032
+ GDScriptParser::ClassNode *class_type = type.class_type ;
2033
+ StringName class_name = (class_type && class_type->identifier ) ? class_type->identifier ->name : " @GlobalScope" ;
2034
+ if (dd && dd->class_list .has (class_name)) {
2035
+ DocData::ClassDoc class_doc = dd->class_list [class_name];
2036
+ if (class_doc.enums .has (enum_type)) {
2037
+ is_deprecated = class_doc.enums [enum_type].is_deprecated ;
2038
+ }
2039
+ }
2040
+ new_value_type = " enum" ;
2041
+ break ;
2042
+ }
2043
+ default :
2044
+ break ;
2045
+ }
2046
+ if (is_deprecated) {
2047
+ parser->push_warning (p_assignable, GDScriptWarning::DEPRECATED_IDENTIFIER, new_value_type, value_name);
2048
+ }
2049
+ #endif
2050
+
1996
2051
if (p_assignable->initializer != nullptr ) {
1997
2052
reduce_expression (p_assignable->initializer );
1998
2053
@@ -3998,6 +4053,38 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
3998
4053
StringName name = p_identifier->name ;
3999
4054
4000
4055
if (base.kind == GDScriptParser::DataType::ENUM) {
4056
+ #if TOOLS_ENABLED
4057
+ StringName class_name;
4058
+ DocTools *dd = EditorHelp::get_doc_data ();
4059
+ // TODO: Is this a proper way of detecting it's from a native class?
4060
+ // e.g., "AnimationPlayer.AnimationProcessCallback"
4061
+ // User-defined enums also seem to have a "native_type" so we can't
4062
+ // detect actual native classes solely based on whether or not that
4063
+ // string is defined.
4064
+ if (base.native_type && !base.class_type ) {
4065
+ class_name = String (base.native_type ).get_slicec (' .' , 0 );
4066
+ }
4067
+
4068
+ else if (base.class_type && base.class_type ->identifier && base.class_type ->identifier ->name ) {
4069
+ class_name = base.class_type ->identifier ->name ;
4070
+ // It's an inner class, so we need to get the outer class's name
4071
+ // as well to construct its full name as found in the doc data.
4072
+ if (base.class_type ->outer != nullptr && base.class_type ->outer ->identifier != nullptr ) {
4073
+ class_name = String (base.class_type ->outer ->identifier ->name ) + " ." + class_name;
4074
+ }
4075
+ }
4076
+
4077
+ if (dd && dd->class_list .has (class_name)) {
4078
+ for (const DocData::ConstantDoc &doc : dd->class_list [class_name].constants ) {
4079
+ if (doc.enumeration == base.enum_type && doc.name == name) {
4080
+ if (doc.is_deprecated ) {
4081
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum value" , vformat (" %s.%s" , base.enum_type , doc.name ));
4082
+ }
4083
+ break ;
4084
+ }
4085
+ }
4086
+ }
4087
+ #endif
4001
4088
if (base.is_meta_type ) {
4002
4089
if (base.enum_values .has (name)) {
4003
4090
p_identifier->set_datatype (type_from_metatype (base));
@@ -4143,6 +4230,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4143
4230
p_identifier->reduced_value = member.constant ->initializer ->reduced_value ;
4144
4231
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4145
4232
p_identifier->constant_source = member.constant ;
4233
+ #if TOOLS_ENABLED
4234
+ if (member.constant ->doc_data .is_deprecated ) {
4235
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , name);
4236
+ }
4237
+ #endif
4146
4238
return ;
4147
4239
}
4148
4240
@@ -4151,6 +4243,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4151
4243
p_identifier->is_constant = true ;
4152
4244
p_identifier->reduced_value = member.enum_value .value ;
4153
4245
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4246
+ #if TOOLS_ENABLED
4247
+ if (member.enum_value .doc_data .is_deprecated ) {
4248
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum value" , name);
4249
+ }
4250
+ #endif
4154
4251
return ;
4155
4252
}
4156
4253
@@ -4159,6 +4256,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4159
4256
p_identifier->is_constant = true ;
4160
4257
p_identifier->reduced_value = member.m_enum ->dictionary ;
4161
4258
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4259
+ #if TOOLS_ENABLED
4260
+ if (member.m_enum ->doc_data .is_deprecated ) {
4261
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum" , name);
4262
+ }
4263
+ #endif
4162
4264
return ;
4163
4265
}
4164
4266
@@ -4168,6 +4270,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4168
4270
p_identifier->source = member.variable ->is_static ? GDScriptParser::IdentifierNode::STATIC_VARIABLE : GDScriptParser::IdentifierNode::MEMBER_VARIABLE;
4169
4271
p_identifier->variable_source = member.variable ;
4170
4272
member.variable ->usages += 1 ;
4273
+ #if TOOLS_ENABLED
4274
+ if (member.variable ->doc_data .is_deprecated ) {
4275
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " property or variable" , name);
4276
+ }
4277
+ #endif
4171
4278
return ;
4172
4279
}
4173
4280
} break ;
@@ -4178,6 +4285,12 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4178
4285
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_SIGNAL;
4179
4286
p_identifier->signal_source = member.signal ;
4180
4287
member.signal ->usages += 1 ;
4288
+
4289
+ #if TOOLS_ENABLED
4290
+ if (member.signal ->doc_data .is_deprecated ) {
4291
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " signal" , name);
4292
+ }
4293
+ #endif
4181
4294
return ;
4182
4295
}
4183
4296
} break ;
@@ -4195,6 +4308,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4195
4308
case GDScriptParser::ClassNode::Member::CLASS: {
4196
4309
reduce_identifier_from_base_set_class (p_identifier, member.get_datatype ());
4197
4310
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CLASS;
4311
+ #ifdef TOOLS_ENABLED
4312
+ if (script_class->get_member (name).m_class ->doc_data .is_deprecated ) {
4313
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4314
+ }
4315
+ #endif
4198
4316
return ;
4199
4317
}
4200
4318
@@ -4284,6 +4402,19 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4284
4402
p_identifier->set_datatype (type_from_property (getter->get_return_info (), false , !has_setter));
4285
4403
p_identifier->source = GDScriptParser::IdentifierNode::INHERITED_VARIABLE;
4286
4404
}
4405
+ #if TOOLS_ENABLED
4406
+ DocTools *dd = EditorHelp::get_doc_data ();
4407
+ if (dd && dd->class_list .has (native)) {
4408
+ for (const DocData::PropertyDoc &doc : dd->class_list [native].properties ) {
4409
+ if (doc.name == name) {
4410
+ if (doc.is_deprecated ) {
4411
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " property" , name);
4412
+ }
4413
+ break ;
4414
+ }
4415
+ }
4416
+ }
4417
+ #endif
4287
4418
return ;
4288
4419
}
4289
4420
if (ClassDB::get_method_info (native, name, &method_info)) {
@@ -4296,11 +4427,33 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4296
4427
// Signal is a type too.
4297
4428
p_identifier->set_datatype (make_signal_type (method_info));
4298
4429
p_identifier->source = GDScriptParser::IdentifierNode::INHERITED_VARIABLE;
4430
+ #if TOOLS_ENABLED
4431
+ DocTools *dd = EditorHelp::get_doc_data ();
4432
+ if (dd && dd->class_list .has (native)) {
4433
+ for (const DocData::MethodDoc &doc : dd->class_list [native].signals ) {
4434
+ if (doc.name == name) {
4435
+ if (doc.is_deprecated ) {
4436
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " signal" , name);
4437
+ }
4438
+ break ;
4439
+ }
4440
+ }
4441
+ }
4442
+ #endif
4299
4443
return ;
4300
4444
}
4301
4445
if (ClassDB::has_enum (native, name)) {
4302
4446
p_identifier->set_datatype (make_native_enum_type (name, native));
4303
4447
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4448
+ #if TOOLS_ENABLED
4449
+ DocTools *dd = EditorHelp::get_doc_data ();
4450
+ if (dd && dd->class_list .has (native) && dd->class_list [native].enums .has (name)) {
4451
+ DocData::EnumDoc doc = dd->class_list [native].enums [name];
4452
+ if (doc.is_deprecated ) {
4453
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum" , name);
4454
+ }
4455
+ }
4456
+ #endif
4304
4457
return ;
4305
4458
}
4306
4459
bool valid = false ;
@@ -4311,6 +4464,20 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4311
4464
p_identifier->reduced_value = int_constant;
4312
4465
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4313
4466
4467
+ #if TOOLS_ENABLED
4468
+ DocTools *dd = EditorHelp::get_doc_data ();
4469
+ if (dd && dd->class_list .has (native)) {
4470
+ for (const DocData::ConstantDoc &doc : dd->class_list [native].constants ) {
4471
+ if (doc.name == name) {
4472
+ if (doc.is_deprecated ) {
4473
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , name);
4474
+ }
4475
+ break ;
4476
+ }
4477
+ }
4478
+ }
4479
+ #endif
4480
+
4314
4481
// Check whether this constant, which exists, belongs to an enum
4315
4482
StringName enum_name = ClassDB::get_integer_constant_enum (native, name);
4316
4483
if (enum_name != StringName ()) {
@@ -4363,6 +4530,12 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4363
4530
// TODO: Constant should have a value on the node itself.
4364
4531
p_identifier->reduced_value = p_identifier->constant_source ->initializer ->reduced_value ;
4365
4532
found_source = true ;
4533
+
4534
+ #ifdef TOOLS_ENABLED
4535
+ if (p_identifier->constant_source ->doc_data .is_deprecated ) {
4536
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , p_identifier->name );
4537
+ }
4538
+ #endif
4366
4539
break ;
4367
4540
case GDScriptParser::IdentifierNode::MEMBER_SIGNAL:
4368
4541
p_identifier->signal_source ->usages ++;
@@ -4382,6 +4555,11 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4382
4555
if (p_identifier->variable_source && p_identifier->variable_source ->assignments == 0 && !(p_identifier->get_datatype ().is_hard_type () && p_identifier->get_datatype ().kind == GDScriptParser::DataType::BUILTIN)) {
4383
4556
parser->push_warning (p_identifier, GDScriptWarning::UNASSIGNED_VARIABLE, p_identifier->name );
4384
4557
}
4558
+ #endif
4559
+ #ifdef TOOLS_ENABLED
4560
+ if (p_identifier->variable_source ->doc_data .is_deprecated ) {
4561
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " property or variable" , p_identifier->name );
4562
+ }
4385
4563
#endif
4386
4564
break ;
4387
4565
case GDScriptParser::IdentifierNode::LOCAL_ITERATOR:
@@ -4499,12 +4677,28 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4499
4677
}
4500
4678
4501
4679
if (class_exists (name)) {
4680
+ #if TOOLS_ENABLED
4681
+ DocTools *dd = EditorHelp::get_doc_data ();
4682
+ if (dd && dd->class_list .has (name)) {
4683
+ if (dd->class_list [name].is_deprecated ) {
4684
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4685
+ }
4686
+ }
4687
+ #endif
4502
4688
p_identifier->set_datatype (make_native_meta_type (name));
4503
4689
return ;
4504
4690
}
4505
4691
4506
4692
if (ScriptServer::is_global_class (name)) {
4507
4693
p_identifier->set_datatype (make_global_class_meta_type (name, p_identifier));
4694
+ #if TOOLS_ENABLED
4695
+ DocTools *dd = EditorHelp::get_doc_data ();
4696
+ if (dd && dd->class_list .has (name)) {
4697
+ if (dd->class_list [name].is_deprecated ) {
4698
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4699
+ }
4700
+ }
4701
+ #endif
4508
4702
return ;
4509
4703
}
4510
4704
@@ -4545,6 +4739,14 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4545
4739
}
4546
4740
}
4547
4741
}
4742
+ #if TOOLS_ENABLED
4743
+ DocTools *dd = EditorHelp::get_doc_data ();
4744
+ if (dd && dd->class_list .has (name)) {
4745
+ if (dd->class_list [name].is_deprecated ) {
4746
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4747
+ }
4748
+ }
4749
+ #endif
4548
4750
result.is_constant = true ;
4549
4751
p_identifier->set_datatype (result);
4550
4752
return ;
@@ -4562,6 +4764,17 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4562
4764
}
4563
4765
p_identifier->is_constant = true ;
4564
4766
p_identifier->reduced_value = value;
4767
+
4768
+ #if TOOLS_ENABLED
4769
+ DocTools *dd = EditorHelp::get_doc_data ();
4770
+ if (dd && dd->class_list .has (" @GlobalScope" )) {
4771
+ for (const DocData::ConstantDoc &cd : dd->class_list [" @GlobalScope" ].constants ) {
4772
+ if (cd.name == name && cd.is_deprecated ) {
4773
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , name);
4774
+ }
4775
+ }
4776
+ }
4777
+ #endif
4565
4778
return ;
4566
4779
}
4567
4780
@@ -5755,6 +5968,12 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, bo
5755
5968
r_return_type.is_meta_type = false ;
5756
5969
r_return_type.is_coroutine = found_function->is_coroutine ;
5757
5970
5971
+ // For user-defined methods.
5972
+ #ifdef TOOLS_ENABLED
5973
+ if (found_function->doc_data .is_deprecated ) {
5974
+ parser->push_warning (p_source, GDScriptWarning::DEPRECATED_IDENTIFIER, " function" , found_function->identifier ->name );
5975
+ }
5976
+ #endif
5758
5977
return true ;
5759
5978
}
5760
5979
@@ -5798,6 +6017,19 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, bo
5798
6017
if (native_method && r_native_class) {
5799
6018
*r_native_class = native_method->get_instance_class ();
5800
6019
}
6020
+ #endif
6021
+ #ifdef TOOLS_ENABLED
6022
+ DocTools *dd = EditorHelp::get_doc_data ();
6023
+ if (dd) {
6024
+ Vector<DocData::MethodDoc> method_list = dd->class_list [base_native].methods ;
6025
+ for (int i = 0 ; i < method_list.size (); i++) {
6026
+ if (method_list[i].name == function_name && method_list[i].is_deprecated ) {
6027
+ parser->push_warning (p_source, GDScriptWarning::DEPRECATED_IDENTIFIER, " function" , function_name);
6028
+ break ;
6029
+ }
6030
+ }
6031
+ }
6032
+
5801
6033
#endif
5802
6034
return valid;
5803
6035
}
0 commit comments