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
+ #ifdef 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
@@ -4003,6 +4058,38 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4003
4058
StringName name = p_identifier->name ;
4004
4059
4005
4060
if (base.kind == GDScriptParser::DataType::ENUM) {
4061
+ #ifdef TOOLS_ENABLED
4062
+ StringName class_name;
4063
+ DocTools *dd = EditorHelp::get_doc_data ();
4064
+ // TODO: Is this a proper way of detecting it's from a native class?
4065
+ // e.g., "AnimationPlayer.AnimationProcessCallback"
4066
+ // User-defined enums also seem to have a "native_type" so we can't
4067
+ // detect actual native classes solely based on whether or not that
4068
+ // string is defined.
4069
+ if (base.native_type && !base.class_type ) {
4070
+ class_name = String (base.native_type ).get_slicec (' .' , 0 );
4071
+ }
4072
+
4073
+ else if (base.class_type && base.class_type ->identifier && base.class_type ->identifier ->name ) {
4074
+ class_name = base.class_type ->identifier ->name ;
4075
+ // It's an inner class, so we need to get the outer class's name
4076
+ // as well to construct its full name as found in the doc data.
4077
+ if (base.class_type ->outer != nullptr && base.class_type ->outer ->identifier != nullptr ) {
4078
+ class_name = String (base.class_type ->outer ->identifier ->name ) + " ." + class_name;
4079
+ }
4080
+ }
4081
+
4082
+ if (dd && dd->class_list .has (class_name)) {
4083
+ for (const DocData::ConstantDoc &doc : dd->class_list [class_name].constants ) {
4084
+ if (doc.enumeration == base.enum_type && doc.name == name) {
4085
+ if (doc.is_deprecated ) {
4086
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum value" , vformat (" %s.%s" , base.enum_type , doc.name ));
4087
+ }
4088
+ break ;
4089
+ }
4090
+ }
4091
+ }
4092
+ #endif
4006
4093
if (base.is_meta_type ) {
4007
4094
if (base.enum_values .has (name)) {
4008
4095
p_identifier->set_datatype (type_from_metatype (base));
@@ -4148,6 +4235,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4148
4235
p_identifier->reduced_value = member.constant ->initializer ->reduced_value ;
4149
4236
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4150
4237
p_identifier->constant_source = member.constant ;
4238
+ #ifdef TOOLS_ENABLED
4239
+ if (member.constant ->doc_data .is_deprecated ) {
4240
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , name);
4241
+ }
4242
+ #endif
4151
4243
return ;
4152
4244
}
4153
4245
@@ -4156,6 +4248,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4156
4248
p_identifier->is_constant = true ;
4157
4249
p_identifier->reduced_value = member.enum_value .value ;
4158
4250
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4251
+ #ifdef TOOLS_ENABLED
4252
+ if (member.enum_value .doc_data .is_deprecated ) {
4253
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum value" , name);
4254
+ }
4255
+ #endif
4159
4256
return ;
4160
4257
}
4161
4258
@@ -4164,6 +4261,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4164
4261
p_identifier->is_constant = true ;
4165
4262
p_identifier->reduced_value = member.m_enum ->dictionary ;
4166
4263
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4264
+ #ifdef TOOLS_ENABLED
4265
+ if (member.m_enum ->doc_data .is_deprecated ) {
4266
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum" , name);
4267
+ }
4268
+ #endif
4167
4269
return ;
4168
4270
}
4169
4271
@@ -4173,6 +4275,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4173
4275
p_identifier->source = member.variable ->is_static ? GDScriptParser::IdentifierNode::STATIC_VARIABLE : GDScriptParser::IdentifierNode::MEMBER_VARIABLE;
4174
4276
p_identifier->variable_source = member.variable ;
4175
4277
member.variable ->usages += 1 ;
4278
+ #ifdef TOOLS_ENABLED
4279
+ if (member.variable ->doc_data .is_deprecated ) {
4280
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " property or variable" , name);
4281
+ }
4282
+ #endif
4176
4283
return ;
4177
4284
}
4178
4285
} break ;
@@ -4183,6 +4290,12 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4183
4290
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_SIGNAL;
4184
4291
p_identifier->signal_source = member.signal ;
4185
4292
member.signal ->usages += 1 ;
4293
+
4294
+ #ifdef TOOLS_ENABLED
4295
+ if (member.signal ->doc_data .is_deprecated ) {
4296
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " signal" , name);
4297
+ }
4298
+ #endif
4186
4299
return ;
4187
4300
}
4188
4301
} break ;
@@ -4200,6 +4313,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4200
4313
case GDScriptParser::ClassNode::Member::CLASS: {
4201
4314
reduce_identifier_from_base_set_class (p_identifier, member.get_datatype ());
4202
4315
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CLASS;
4316
+ #ifdef TOOLS_ENABLED
4317
+ if (script_class->get_member (name).m_class ->doc_data .is_deprecated ) {
4318
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4319
+ }
4320
+ #endif
4203
4321
return ;
4204
4322
}
4205
4323
@@ -4289,6 +4407,19 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4289
4407
p_identifier->set_datatype (type_from_property (getter->get_return_info (), false , !has_setter));
4290
4408
p_identifier->source = GDScriptParser::IdentifierNode::INHERITED_VARIABLE;
4291
4409
}
4410
+ #ifdef TOOLS_ENABLED
4411
+ DocTools *dd = EditorHelp::get_doc_data ();
4412
+ if (dd && dd->class_list .has (native)) {
4413
+ for (const DocData::PropertyDoc &doc : dd->class_list [native].properties ) {
4414
+ if (doc.name == name) {
4415
+ if (doc.is_deprecated ) {
4416
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " property" , name);
4417
+ }
4418
+ break ;
4419
+ }
4420
+ }
4421
+ }
4422
+ #endif
4292
4423
return ;
4293
4424
}
4294
4425
if (ClassDB::get_method_info (native, name, &method_info)) {
@@ -4301,11 +4432,33 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4301
4432
// Signal is a type too.
4302
4433
p_identifier->set_datatype (make_signal_type (method_info));
4303
4434
p_identifier->source = GDScriptParser::IdentifierNode::INHERITED_VARIABLE;
4435
+ #ifdef TOOLS_ENABLED
4436
+ DocTools *dd = EditorHelp::get_doc_data ();
4437
+ if (dd && dd->class_list .has (native)) {
4438
+ for (const DocData::MethodDoc &doc : dd->class_list [native].signals ) {
4439
+ if (doc.name == name) {
4440
+ if (doc.is_deprecated ) {
4441
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " signal" , name);
4442
+ }
4443
+ break ;
4444
+ }
4445
+ }
4446
+ }
4447
+ #endif
4304
4448
return ;
4305
4449
}
4306
4450
if (ClassDB::has_enum (native, name)) {
4307
4451
p_identifier->set_datatype (make_native_enum_type (name, native));
4308
4452
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4453
+ #ifdef TOOLS_ENABLED
4454
+ DocTools *dd = EditorHelp::get_doc_data ();
4455
+ if (dd && dd->class_list .has (native) && dd->class_list [native].enums .has (name)) {
4456
+ DocData::EnumDoc doc = dd->class_list [native].enums [name];
4457
+ if (doc.is_deprecated ) {
4458
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " enum" , name);
4459
+ }
4460
+ }
4461
+ #endif
4309
4462
return ;
4310
4463
}
4311
4464
bool valid = false ;
@@ -4316,6 +4469,20 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
4316
4469
p_identifier->reduced_value = int_constant;
4317
4470
p_identifier->source = GDScriptParser::IdentifierNode::MEMBER_CONSTANT;
4318
4471
4472
+ #ifdef TOOLS_ENABLED
4473
+ DocTools *dd = EditorHelp::get_doc_data ();
4474
+ if (dd && dd->class_list .has (native)) {
4475
+ for (const DocData::ConstantDoc &doc : dd->class_list [native].constants ) {
4476
+ if (doc.name == name) {
4477
+ if (doc.is_deprecated ) {
4478
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , name);
4479
+ }
4480
+ break ;
4481
+ }
4482
+ }
4483
+ }
4484
+ #endif
4485
+
4319
4486
// Check whether this constant, which exists, belongs to an enum
4320
4487
StringName enum_name = ClassDB::get_integer_constant_enum (native, name);
4321
4488
if (enum_name != StringName ()) {
@@ -4368,6 +4535,12 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4368
4535
// TODO: Constant should have a value on the node itself.
4369
4536
p_identifier->reduced_value = p_identifier->constant_source ->initializer ->reduced_value ;
4370
4537
found_source = true ;
4538
+
4539
+ #ifdef TOOLS_ENABLED
4540
+ if (p_identifier->constant_source ->doc_data .is_deprecated ) {
4541
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , p_identifier->name );
4542
+ }
4543
+ #endif
4371
4544
break ;
4372
4545
case GDScriptParser::IdentifierNode::MEMBER_SIGNAL:
4373
4546
p_identifier->signal_source ->usages ++;
@@ -4387,6 +4560,11 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4387
4560
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)) {
4388
4561
parser->push_warning (p_identifier, GDScriptWarning::UNASSIGNED_VARIABLE, p_identifier->name );
4389
4562
}
4563
+ #endif
4564
+ #ifdef TOOLS_ENABLED
4565
+ if (p_identifier->variable_source ->doc_data .is_deprecated ) {
4566
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " property or variable" , p_identifier->name );
4567
+ }
4390
4568
#endif
4391
4569
break ;
4392
4570
case GDScriptParser::IdentifierNode::LOCAL_ITERATOR:
@@ -4504,12 +4682,28 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4504
4682
}
4505
4683
4506
4684
if (class_exists (name)) {
4685
+ #ifdef TOOLS_ENABLED
4686
+ DocTools *dd = EditorHelp::get_doc_data ();
4687
+ if (dd && dd->class_list .has (name)) {
4688
+ if (dd->class_list [name].is_deprecated ) {
4689
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4690
+ }
4691
+ }
4692
+ #endif
4507
4693
p_identifier->set_datatype (make_native_meta_type (name));
4508
4694
return ;
4509
4695
}
4510
4696
4511
4697
if (ScriptServer::is_global_class (name)) {
4512
4698
p_identifier->set_datatype (make_global_class_meta_type (name, p_identifier));
4699
+ #ifdef TOOLS_ENABLED
4700
+ DocTools *dd = EditorHelp::get_doc_data ();
4701
+ if (dd && dd->class_list .has (name)) {
4702
+ if (dd->class_list [name].is_deprecated ) {
4703
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4704
+ }
4705
+ }
4706
+ #endif
4513
4707
return ;
4514
4708
}
4515
4709
@@ -4550,6 +4744,14 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4550
4744
}
4551
4745
}
4552
4746
}
4747
+ #ifdef TOOLS_ENABLED
4748
+ DocTools *dd = EditorHelp::get_doc_data ();
4749
+ if (dd && dd->class_list .has (name)) {
4750
+ if (dd->class_list [name].is_deprecated ) {
4751
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " class" , name);
4752
+ }
4753
+ }
4754
+ #endif
4553
4755
result.is_constant = true ;
4554
4756
p_identifier->set_datatype (result);
4555
4757
return ;
@@ -4567,6 +4769,17 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident
4567
4769
}
4568
4770
p_identifier->is_constant = true ;
4569
4771
p_identifier->reduced_value = value;
4772
+
4773
+ #ifdef TOOLS_ENABLED
4774
+ DocTools *dd = EditorHelp::get_doc_data ();
4775
+ if (dd && dd->class_list .has (" @GlobalScope" )) {
4776
+ for (const DocData::ConstantDoc &cd : dd->class_list [" @GlobalScope" ].constants ) {
4777
+ if (cd.name == name && cd.is_deprecated ) {
4778
+ parser->push_warning (p_identifier, GDScriptWarning::DEPRECATED_IDENTIFIER, " constant" , name);
4779
+ }
4780
+ }
4781
+ }
4782
+ #endif
4570
4783
return ;
4571
4784
}
4572
4785
@@ -5812,6 +6025,12 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, bo
5812
6025
r_return_type.is_meta_type = false ;
5813
6026
r_return_type.is_coroutine = found_function->is_coroutine ;
5814
6027
6028
+ // For user-defined methods.
6029
+ #ifdef TOOLS_ENABLED
6030
+ if (found_function->doc_data .is_deprecated ) {
6031
+ parser->push_warning (p_source, GDScriptWarning::DEPRECATED_IDENTIFIER, " function" , found_function->identifier ->name );
6032
+ }
6033
+ #endif
5815
6034
return true ;
5816
6035
}
5817
6036
@@ -5855,6 +6074,19 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, bo
5855
6074
if (native_method && r_native_class) {
5856
6075
*r_native_class = native_method->get_instance_class ();
5857
6076
}
6077
+ #endif
6078
+ #ifdef TOOLS_ENABLED
6079
+ DocTools *dd = EditorHelp::get_doc_data ();
6080
+ if (dd) {
6081
+ const Vector<DocData::MethodDoc> &method_list = dd->class_list [base_native].methods ;
6082
+ for (int i = 0 ; i < method_list.size (); i++) {
6083
+ if (method_list[i].name == function_name && method_list[i].is_deprecated ) {
6084
+ parser->push_warning (p_source, GDScriptWarning::DEPRECATED_IDENTIFIER, " function" , function_name);
6085
+ break ;
6086
+ }
6087
+ }
6088
+ }
6089
+
5858
6090
#endif
5859
6091
return valid;
5860
6092
}
0 commit comments