This is an automated email from the ASF dual-hosted git repository. jensg pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/thrift.git
The following commit(s) were added to refs/heads/master by this push: new 4115e952b THRIFT-5746 Upgrade to net8 Client: netstd Patch: Jens Geyer 4115e952b is described below commit 4115e952b5bed2887113af053b63acd3a03c6e19 Author: Jens Geyer <je...@apache.org> AuthorDate: Tue Nov 21 23:00:01 2023 +0100 THRIFT-5746 Upgrade to net8 Client: netstd Patch: Jens Geyer --- build/docker/old/debian-stretch/Dockerfile | 8 +- build/docker/old/ubuntu-artful/Dockerfile | 8 +- build/docker/old/ubuntu-disco/Dockerfile | 8 +- build/docker/old/ubuntu-xenial/Dockerfile | 8 +- build/docker/ubuntu-bionic/Dockerfile | 8 +- build/docker/ubuntu-focal/Dockerfile | 8 +- build/docker/ubuntu-jammy/Dockerfile | 8 +- .../cpp/src/thrift/generate/t_netstd_generator.cc | 225 ++++++++++++++------- .../cpp/src/thrift/generate/t_netstd_generator.h | 6 +- .../Thrift.Benchmarks/Thrift.Benchmarks.csproj | 3 +- .../Thrift.IntegrationTests.csproj | 3 +- .../Thrift.PublicInterfaces.Compile.Tests.csproj | 19 +- .../Thrift.Tests/Collections/TCollectionsTests.cs | 40 ++-- .../Tests/Thrift.Tests/DataModel/DeepCopy.cs | 79 +++----- .../Tests/Thrift.Tests/DataModel/NullValuesSet.cs | 1 + .../Protocols/TJsonProtocolHelperTests.cs | 54 ++--- .../Thrift.Tests/Protocols/TJsonProtocolTests.cs | 6 +- lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj | 3 +- lib/netstd/Thrift/.editorconfig | 5 + .../Thrift/Processor/TMultiplexedProcessor.cs | 8 +- .../Thrift/Processor/TSingletonProcessorFactory.cs | 7 +- lib/netstd/Thrift/Protocol/Entities/TField.cs | 5 +- lib/netstd/Thrift/Protocol/Entities/TList.cs | 5 +- lib/netstd/Thrift/Protocol/Entities/TMap.cs | 5 +- lib/netstd/Thrift/Protocol/Entities/TMessage.cs | 5 +- lib/netstd/Thrift/Protocol/Entities/TSet.cs | 5 +- lib/netstd/Thrift/Protocol/Entities/TStruct.cs | 3 + lib/netstd/Thrift/Protocol/TBinaryProtocol.cs | 17 +- lib/netstd/Thrift/Protocol/TCompactProtocol.cs | 2 + lib/netstd/Thrift/Protocol/TJSONProtocol.cs | 2 + lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs | 3 + lib/netstd/Thrift/Protocol/ToString.cs | 20 +- .../Thrift/Protocol/Utilities/TBase64Utils.cs | 8 +- .../Thrift/Protocol/Utilities/TGuidExtensions.cs | 4 +- .../Protocol/Utilities/TJsonProtocolConstants.cs | 3 + lib/netstd/Thrift/Server/TServer.cs | 3 +- lib/netstd/Thrift/Server/TSimpleAsyncServer.cs | 2 + lib/netstd/Thrift/Thrift.csproj | 2 +- .../Thrift/Transport/Client/TTlsSocketTransport.cs | 3 + .../Thrift/Transport/Layered/TFramedTransport.cs | 4 + .../Thrift/Transport/Layered/TLayeredTransport.cs | 7 +- .../Transport/Server/TNamedPipeServerTransport.cs | 10 +- .../Transport/Server/TServerSocketTransport.cs | 3 + .../Thrift/Transport/Server/TServerTransport.cs | 13 +- lib/netstd/Thrift/Transport/TTransport.cs | 6 +- test/netstd/Client/Client.csproj | 10 +- test/netstd/Client/Performance/PerformanceTests.cs | 6 +- test/netstd/Client/TestClient.cs | 24 +-- test/netstd/Server/Server.csproj | 10 +- test/netstd/Server/TestServer.cs | 25 ++- tutorial/netstd/Client/Client.csproj | 4 +- tutorial/netstd/Interfaces/Interfaces.csproj | 2 +- tutorial/netstd/Server/Server.csproj | 4 +- 53 files changed, 426 insertions(+), 314 deletions(-) diff --git a/build/docker/old/debian-stretch/Dockerfile b/build/docker/old/debian-stretch/Dockerfile index 25237cabf..f584bba9a 100644 --- a/build/docker/old/debian-stretch/Dockerfile +++ b/build/docker/old/debian-stretch/Dockerfile @@ -102,10 +102,10 @@ ENV PATH /usr/lib/dart/bin:$PATH # project isn't ready for this quite yet: # RUN apt-get install -y --no-install-recommends \ # `# dotnet core dependencies` \ -# dotnet-sdk-7.0 \ -# dotnet-runtime-7.0 \ -# aspnetcore-runtime-7.0 \ -# dotnet-apphost-pack-7.0 +# dotnet-sdk-8.0 \ +# dotnet-runtime-8.0 \ +# aspnetcore-runtime-8.0 \ +# dotnet-apphost-pack-8.0 RUN apt-get install -y --no-install-recommends \ `# Erlang dependencies` \ diff --git a/build/docker/old/ubuntu-artful/Dockerfile b/build/docker/old/ubuntu-artful/Dockerfile index 039147033..f94b70086 100644 --- a/build/docker/old/ubuntu-artful/Dockerfile +++ b/build/docker/old/ubuntu-artful/Dockerfile @@ -120,10 +120,10 @@ ENV PATH /usr/lib/dart/bin:$PATH RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-7.0 \ - dotnet-runtime-7.0 \ - aspnetcore-runtime-7.0 \ - dotnet-apphost-pack-7.0 + dotnet-sdk-8.0 \ + dotnet-runtime-8.0 \ + aspnetcore-runtime-8.0 \ + dotnet-apphost-pack-8.0 RUN apt-get install -y --no-install-recommends \ `# Erlang dependencies` \ diff --git a/build/docker/old/ubuntu-disco/Dockerfile b/build/docker/old/ubuntu-disco/Dockerfile index d2f397a60..39642cf2b 100644 --- a/build/docker/old/ubuntu-disco/Dockerfile +++ b/build/docker/old/ubuntu-disco/Dockerfile @@ -126,10 +126,10 @@ ENV PATH /usr/lib/dart/bin:$PATH RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-7.0 \ - dotnet-runtime-7.0 \ - aspnetcore-runtime-7.0 \ - dotnet-apphost-pack-7.0 + dotnet-sdk-8.0 \ + dotnet-runtime-8.0 \ + aspnetcore-runtime-8.0 \ + dotnet-apphost-pack-8.0 RUN apt-get install -y --no-install-recommends \ `# Erlang dependencies` \ diff --git a/build/docker/old/ubuntu-xenial/Dockerfile b/build/docker/old/ubuntu-xenial/Dockerfile index 37df80f8c..d9d87ccae 100644 --- a/build/docker/old/ubuntu-xenial/Dockerfile +++ b/build/docker/old/ubuntu-xenial/Dockerfile @@ -115,10 +115,10 @@ ENV PATH /usr/lib/dart/bin:$PATH RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-7.0 \ - dotnet-runtime-7.0 \ - aspnetcore-runtime-7.0 \ - dotnet-apphost-pack-7.0 + dotnet-sdk-8.0 \ + dotnet-runtime-8.0 \ + aspnetcore-runtime-8.0 \ + dotnet-apphost-pack-8.0 # Erlang dependencies ARG ERLANG_OTP_VERSION=20.3.8.9 diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile index 00c7de359..350921ae5 100644 --- a/build/docker/ubuntu-bionic/Dockerfile +++ b/build/docker/ubuntu-bionic/Dockerfile @@ -124,10 +124,10 @@ ENV PATH /usr/lib/dart/bin:$PATH RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-7.0 \ - dotnet-runtime-7.0 \ - aspnetcore-runtime-7.0 \ - dotnet-apphost-pack-7.0 + dotnet-sdk-8.0 \ + dotnet-runtime-8.0 \ + aspnetcore-runtime-8.0 \ + dotnet-apphost-pack-8.0 # Erlang dependencies ARG ERLANG_OTP_VERSION=23.3.4.11 diff --git a/build/docker/ubuntu-focal/Dockerfile b/build/docker/ubuntu-focal/Dockerfile index 1039e459d..416e80646 100644 --- a/build/docker/ubuntu-focal/Dockerfile +++ b/build/docker/ubuntu-focal/Dockerfile @@ -125,10 +125,10 @@ ENV PATH /usr/lib/dart/bin:$PATH RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-7.0 \ - dotnet-runtime-7.0 \ - aspnetcore-runtime-7.0 \ - dotnet-apphost-pack-7.0 + dotnet-sdk-8.0 \ + dotnet-runtime-8.0 \ + aspnetcore-runtime-8.0 \ + dotnet-apphost-pack-8.0 # Erlang dependencies ARG ERLANG_OTP_VERSION=23.3.4.11 diff --git a/build/docker/ubuntu-jammy/Dockerfile b/build/docker/ubuntu-jammy/Dockerfile index d45070f45..a10fea650 100644 --- a/build/docker/ubuntu-jammy/Dockerfile +++ b/build/docker/ubuntu-jammy/Dockerfile @@ -125,10 +125,10 @@ ENV PATH /usr/lib/dart/bin:$PATH RUN apt-get install -y --no-install-recommends \ `# dotnet core dependencies` \ - dotnet-sdk-7.0 \ - dotnet-runtime-7.0 \ - aspnetcore-runtime-7.0 \ - dotnet-apphost-pack-7.0 + dotnet-sdk-8.0 \ + dotnet-runtime-8.0 \ + aspnetcore-runtime-8.0 \ + dotnet-apphost-pack-8.0 # Erlang dependencies ARG ERLANG_OTP_VERSION=23.3.4.11 diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc index 1c9700299..1a27c0c3b 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc @@ -51,7 +51,7 @@ t_netstd_generator::t_netstd_generator(t_program* program, const map<string, str : t_oop_generator(program) { (void)option_string; - use_net6_features = false; + target_net_version = 0; suppress_deepcopy = false; add_async_postfix = false; use_pascal_case_properties = false; @@ -83,7 +83,10 @@ t_netstd_generator::t_netstd_generator(t_program* program, const map<string, str suppress_deepcopy = true; } else if (iter->first.compare("net6") == 0) { - use_net6_features = true; + target_net_version = 6; + } + else if (iter->first.compare("net8") == 0) { + target_net_version = 8; } else if (iter->first.compare("async_postfix") == 0) { add_async_postfix = true; @@ -153,13 +156,13 @@ void t_netstd_generator::init_generator() } pverbose(".NET Standard options:\n"); - pverbose("- union ........... %s\n", (is_union_enabled() ? "ON" : "off")); - pverbose("- serialize ....... %s\n", (is_serialize_enabled() ? "ON" : "off")); - pverbose("- wcf ............. %s\n", (is_wcf_enabled() ? "ON" : "off")); - pverbose("- pascal .......... %s\n", (use_pascal_case_properties ? "ON" : "off")); - pverbose("- net6 ............ %s\n", (use_net6_features ? "ON" : "off")); - pverbose("- no_deepcopy ..... %s\n", (suppress_deepcopy ? "ON" : "off")); - pverbose("- async_postfix ... %s\n", (add_async_postfix ? "ON" : "off")); + pverbose("- union ................ %s\n", (is_union_enabled() ? "ON" : "off")); + pverbose("- serialize ............ %s\n", (is_serialize_enabled() ? "ON" : "off")); + pverbose("- wcf .................. %s\n", (is_wcf_enabled() ? "ON" : "off")); + pverbose("- pascal ............... %s\n", (use_pascal_case_properties ? "ON" : "off")); + pverbose("- target NET version ... %d\n", target_net_version); + pverbose("- no_deepcopy .......... %s\n", (suppress_deepcopy ? "ON" : "off")); + pverbose("- async_postfix ........ %s\n", (add_async_postfix ? "ON" : "off")); } string t_netstd_generator::normalize_name(string name, bool is_arg_name) @@ -180,7 +183,7 @@ string t_netstd_generator::normalize_name(string name, bool is_arg_name) } // prevent CS8981 "The type name only contains lower-cased ascii characters" - if( name.find_first_not_of("abcdefghijklmnopqrstuvwxyz") == std::string::npos) + if( name.find_first_not_of("abcdefghijklmnopqrstuvwxyz") == std::string::npos) { return "@" + name; } @@ -199,19 +202,24 @@ void t_netstd_generator::reset_indent() { void t_netstd_generator::pragmas_and_directives(ostream& out) { - if( use_net6_features) { + if( target_net_version >= 6) { + out << "// Thrift code generated for net" << target_net_version << endl; out << "#nullable enable // requires C# 8.0" << endl; } // this one must be first out << "#pragma warning disable IDE0079 // remove unnecessary pragmas" << endl; - out << "#pragma warning disable IDE0017 // object init can be simplified" << endl - << "#pragma warning disable IDE0028 // collection init can be simplified" << endl - << "#pragma warning disable IDE1006 // parts of the code use IDL spelling" << endl - << "#pragma warning disable CA1822 // empty " << DEEP_COPY_METHOD_NAME << "() methods still non-static" << endl; + if( target_net_version >= 8) { + out << "#pragma warning disable IDE0290 // use primary CTOR" << endl; + } else { + out << "#pragma warning disable IDE0017 // object init can be simplified" << endl; + out << "#pragma warning disable IDE0028 // collection init can be simplified" << endl; + } + out << "#pragma warning disable IDE1006 // parts of the code use IDL spelling" << endl; + out << "#pragma warning disable CA1822 // empty " << DEEP_COPY_METHOD_NAME << "() methods still non-static" << endl; - if( ! use_net6_features) { + if( target_net_version < 6) { out << "#pragma warning disable IDE0083 // pattern matching \"that is not SomeType\" requires net5.0 but we still support earlier versions" << endl; } out << endl; @@ -474,7 +482,13 @@ bool t_netstd_generator::print_const_value(ostream& out, string name, t_type* ty if (!defval || needtype) { - out << (in_static ? "" : type->is_base_type() ? "public const " : "public static ") << type_name(type) << " "; + if(in_static) { + out << type_name(type) << " "; + } else if(type->is_base_type()) { + out << "public const " << type_name(type) << " "; + } else { + out << "public static " << (target_net_version >= 6 ? "readonly " : "") << type_name(type) << " "; + } } if (type->is_base_type()) @@ -490,15 +504,21 @@ bool t_netstd_generator::print_const_value(ostream& out, string name, t_type* ty } else if (type->is_struct() || type->is_xception()) { - out << name << " = new " << type_name(type) << "();" << endl; - } - else if (type->is_map()) - { - out << name << " = new " << type_name(type) << "();" << endl; + if(target_net_version >= 6) { + out << name << " = new();" << endl; + } else { + out << name << " = new " << type_name(type) << "();" << endl; + } } - else if (type->is_list() || type->is_set()) + else if (type->is_map() || type->is_list() || type->is_set()) { - out << name << " = new " << type_name(type) << "();" << endl; + if(target_net_version >= 8) { + out << name << " = [];" << endl; + } else if(target_net_version >= 6) { + out << name << " = new();" << endl; + } else { + out << name << " = new " << type_name(type) << "();" << endl; + } } if (defval && !type->is_base_type() && !type->is_enum()) @@ -667,7 +687,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map<string, t_type*> { out << indent() << "public static bool Equals(this " << iter->first << " instance, object that)" << endl; scope_up(out); - if( use_net6_features) { + if( target_net_version >= 6) { out << indent() << "if (that is not " << iter->first << " other) return false;" << endl; } else { out << indent() << "if (!(that is " << iter->first << " other)) return false;" << endl; @@ -705,7 +725,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map<string, t_type*> out << indent() << "foreach (var pair in source)" << endl; indent_up(); - if( use_net6_features) { + if( target_net_version >= 6) { out << indent() << tmp_instance << ".Add(pair.Key" << copy_key; out << ", pair.Value" << copy_val; } else { @@ -743,7 +763,7 @@ void t_netstd_generator::generate_extensions(ostream& out, map<string, t_type*> out << indent() << "foreach (var elem in source)" << endl; indent_up(); - if( use_net6_features) { + if( target_net_version >= 6) { out << indent() << tmp_instance << ".Add(elem" << copy_elm; } else { out << indent() << tmp_instance << ".Add("; @@ -1077,7 +1097,14 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* // return directly if there are only required fields string tmp_instance = tmp("tmp"); - out << indent() << "var " << tmp_instance << " = new " << sharp_struct_name << "();" << endl; + out << indent() << "var " << tmp_instance << " = new " << sharp_struct_name << "()"; + bool inline_assignment = (target_net_version >= 6); + if(inline_assignment) { + out << endl << indent() << "{" << endl; + indent_up(); + } else { + out << endl; + } for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { bool needs_typecast = false; @@ -1086,21 +1113,46 @@ void t_netstd_generator::generate_netstd_deepcopy_method(ostream& out, t_struct* string copy_op = get_deep_copy_method_call(ttype, true, needs_typecast, suffix); bool is_required = field_is_required(*m_iter); + bool null_allowed = type_can_be_null((*m_iter)->get_type()); + + if(inline_assignment) { + if( null_allowed || (!is_required)) { // = has isset + indent_down(); + out << indent() << "};" << endl; + inline_assignment = false; + } + } + generate_null_check_begin( out, *m_iter); - out << indent() << tmp_instance << "." << prop_name(*m_iter) << " = "; + out << indent(); + if(!inline_assignment) { + out << tmp_instance << "."; + } + out << prop_name(*m_iter) << " = "; if( needs_typecast) { out << "(" << type_name(ttype) << ")"; } - out << "this." << prop_name(*m_iter) << copy_op << ";" << endl; + out << "this." << prop_name(*m_iter) << copy_op; + out << (inline_assignment ? "," : ";") << endl; generate_null_check_end( out, *m_iter); if( !is_required) { - out << indent() << tmp_instance << ".__isset." << get_isset_name(normalize_name((*m_iter)->get_name())) - << " = this.__isset." << get_isset_name(normalize_name((*m_iter)->get_name())) << ";" << endl; + out << indent(); + if(!inline_assignment) { + out << tmp_instance << "."; + } + out << "__isset." << get_isset_name(normalize_name((*m_iter)->get_name())); + out << " = this.__isset." << get_isset_name(normalize_name((*m_iter)->get_name())); + out << (inline_assignment ? "," : ";") << endl; } } + if(inline_assignment) { + indent_down(); + out << indent() << "};" << endl; + } + out << indent() << "return " << tmp_instance << ";" << endl; indent_down(); @@ -1271,6 +1323,9 @@ void t_netstd_generator::generate_netstd_struct_writer(ostream& out, t_struct* t if (fields.size() > 0) { tmpvar = tmp("tmp"); + if(target_net_version >= 8) { + out << indent() << "#pragma warning disable IDE0017 // simplified init" << endl; + } out << indent() << "var " << tmpvar << " = new TField();" << endl; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { @@ -1285,6 +1340,9 @@ void t_netstd_generator::generate_netstd_struct_writer(ostream& out, t_struct* t out << indent() << "await oprot.WriteFieldEndAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl; generate_null_check_end(out, *f_iter); } + if(target_net_version >= 8) { + out << indent() << "#pragma warning restore IDE0017 // simplified init" << endl; + } } out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl @@ -1323,6 +1381,9 @@ void t_netstd_generator::generate_netstd_struct_result_writer(ostream& out, t_st if (fields.size() > 0) { tmpvar = tmp("tmp"); + if(target_net_version >= 8) { + out << indent() << "#pragma warning disable IDE0017 // simplified init" << endl; + } out << indent() << "var " << tmpvar << " = new TField();" << endl; bool first = true; for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) @@ -1367,6 +1428,9 @@ void t_netstd_generator::generate_netstd_struct_result_writer(ostream& out, t_st indent_down(); out << indent() << "}" << endl; } + if(target_net_version >= 8) { + out << indent() << "#pragma warning restore IDE0017 // simplified init" << endl; + } } out << indent() << "await oprot.WriteFieldStopAsync(" << CANCELLATION_TOKEN_NAME << ");" << endl @@ -1481,7 +1545,7 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl; scope_up(out); - if( use_net6_features) { + if( target_net_version >= 6) { out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << endl; } else { out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << endl; @@ -1490,7 +1554,7 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct out << endl; out << indent() << "if(this.Isset != other.Isset) return false;" << endl; out << endl; - if(use_net6_features) { + if(target_net_version >= 6) { out << indent() << "return Isset switch" << endl; scope_up(out); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) @@ -1528,13 +1592,13 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct out << indent() << "public override int GetHashCode()" << endl; out << indent() << "{" << endl; indent_up(); - if(use_net6_features) { + if(target_net_version >= 6) { out << indent() << "return Isset switch" << endl; out << indent() << "{" << endl; indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - string null_coalesce(is_nullable_type((*f_iter)->get_type()) ? "?" : ""); + string null_coalesce(is_nullable_type((*f_iter)->get_type()) ? "?" : ""); out << indent() << (*f_iter)->get_key() << " => As_" << (*f_iter)->get_name() << null_coalesce << ".GetHashCode()"; if( null_coalesce.size() > 0) { out << " ?? 0"; @@ -1550,7 +1614,7 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct indent_up(); for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) { - string null_coalesce(is_nullable_type((*f_iter)->get_type()) ? "?" : ""); + string null_coalesce(is_nullable_type((*f_iter)->get_type()) ? "?" : ""); out << indent() << "case " << (*f_iter)->get_key() << ":" << endl; indent_up(); out << indent() << "return As_" << (*f_iter)->get_name() << null_coalesce << ".GetHashCode()"; @@ -1574,7 +1638,7 @@ void t_netstd_generator::generate_netstd_union_definition(ostream& out, t_struct out << indent() << "public " << tunion->get_name() << " " << DEEP_COPY_METHOD_NAME << "()" << endl; out << indent() << "{" << endl; indent_up(); - if(use_net6_features) { + if(target_net_version >= 6) { out << indent() << "return Isset switch" << endl; out << indent() << "{" << endl; indent_up(); @@ -1666,7 +1730,7 @@ void t_netstd_generator::generate_netstd_union_class(ostream& out, t_struct* tun out << indent() << "return (" << tfield->get_key() << " == Isset) && (Data != null)" << " ? (" << type_name(tfield->get_type()) << nullable_field_suffix(tfield) << ")Data" << " : default" - << (use_net6_features ? "" : ("(" + type_name(tfield->get_type()) + ")")) + << (target_net_version >= 6 ? "" : ("(" + type_name(tfield->get_type()) + ")")) << ";" << endl; indent_down(); out << indent() << "}" << endl; @@ -1703,7 +1767,7 @@ void t_netstd_generator::generate_netstd_union_class(ostream& out, t_struct* tun out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl; out << indent() << "{" << endl; indent_up(); - if(use_net6_features) { + if(target_net_version >= 6) { out << indent() << "if (that is not " << tunion->get_name() << " other) return false;" << endl; } else { out << indent() << "if (!(that is " << tunion->get_name() << " other)) return false;" << endl; @@ -1732,11 +1796,15 @@ void t_netstd_generator::generate_netstd_union_class(ostream& out, t_struct* tun out << indent() << "var struc = new TStruct(\"" << tunion->get_name() << "\");" << endl << indent() << "await oprot.WriteStructBeginAsync(struc, " << CANCELLATION_TOKEN_NAME << ");" << endl; - out << indent() << "var field = new TField();" << endl - << indent() << "field.Name = \"" << tfield->get_name() << "\";" << endl - << indent() << "field.Type = " << type_to_enum(tfield->get_type()) << ";" << endl - << indent() << "field.ID = " << tfield->get_key() << ";" << endl - << indent() << "await oprot.WriteFieldBeginAsync(field, " << CANCELLATION_TOKEN_NAME << ");" << endl; + out << indent() << "var field = new TField()" << endl; + out << indent() << "{" << endl; + indent_up(); + out << indent() << "Name = \"" << tfield->get_name() << "\"," << endl + << indent() << "Type = " << type_to_enum(tfield->get_type()) << "," << endl + << indent() << "ID = " << tfield->get_key() << endl; + indent_down(); + out << indent() << "};" << endl; + out << indent() << "await oprot.WriteFieldBeginAsync(field, " << CANCELLATION_TOKEN_NAME << ");" << endl; generate_serialize_field(out, tfield, "_data", true, false); @@ -1762,7 +1830,7 @@ void t_netstd_generator::generate_netstd_struct_equals(ostream& out, t_struct* t out << indent() << "public override bool Equals(object" << nullable_suffix() << " that)" << endl << indent() << "{" << endl; indent_up(); - if(use_net6_features) { + if(target_net_version >= 6) { out << indent() << "if (that is not " << type_name(tstruct,false) << " other) return false;" << endl; } else { out << indent() << "if (!(that is " << type_name(tstruct,false) << " other)) return false;" << endl; @@ -2203,9 +2271,14 @@ void t_netstd_generator::generate_service_server(ostream& out, t_service* tservi if (extends.empty()) { - out << indent() << "protected Dictionary<string, ProcessFunction> processMap_ = new" - << (use_net6_features ? "" : " Dictionary<string, ProcessFunction>") // Simplify new expression (IDE0090) - << "();" << endl; + out << indent() << "protected Dictionary<string, ProcessFunction> processMap_ = "; + if(target_net_version >= 8) { + out << "[];" << endl; + } else if(target_net_version >= 6) { + out << "new();" << endl; + } else { + out << "new Dictionary<string, ProcessFunction>();" << endl; + } } out << endl; @@ -2960,7 +3033,7 @@ void t_netstd_generator::generate_netstd_property(ostream& out, t_field* tfield, if (is_required) { out << " { get; set; }"; - if( use_net6_features && (!force_member_nullable(tfield))) { + if( (target_net_version >= 6) && (!force_member_nullable(tfield))) { out << initialize_field(tfield) << ";"; } out << endl; @@ -3258,7 +3331,7 @@ bool t_netstd_generator::is_nullable_type(t_type* ttype) { string t_netstd_generator::nullable_suffix() { - if(use_net6_features) { + if(target_net_version >= 6) { return "?"; } else { return ""; @@ -3272,10 +3345,10 @@ string t_netstd_generator::nullable_field_suffix(t_field* tfield) { else return nullable_field_suffix(tfield->get_type()); } - + string t_netstd_generator::nullable_field_suffix(t_type* ttype) { - if( ! use_net6_features) { + if( target_net_version < 6) { return ""; } @@ -3300,7 +3373,7 @@ string t_netstd_generator::nullable_field_suffix(t_type* ttype) { } string t_netstd_generator::nullable_value_access(t_type* ttype) { - if( ! use_net6_features) + if( target_net_version < 6) return ""; ttype = resolve_typedef(ttype); @@ -3326,9 +3399,9 @@ string t_netstd_generator::nullable_value_access(t_type* ttype) { } bool t_netstd_generator::force_member_nullable(t_field* tfield) { - // IMPORTANT: + // IMPORTANT: // If tfield is a struct that contains a required field of the same type (directly or indirectly), - // auto-initializing such a member field would immediately produce an OOM, or at least unexpectedly + // auto-initializing such a member field would immediately produce an OOM, or at least unexpectedly // allocate potentially large amounts of memory -> ALWAYS leave containers and struct members nullable t_type* ttype = resolve_typedef(tfield->get_type()); return ttype->is_struct() || ttype->is_container(); @@ -3427,12 +3500,15 @@ string t_netstd_generator::get_deep_copy_method_call(t_type* ttype, bool is_not_ case t_base_type::TYPE_STRING: if (ttype->is_binary()) { suffix = nullable_suffix(); - if( use_net6_features) { + if( target_net_version >= 8) { + null_check = is_not_null ? "!" : " ?? []"; + } + else if( target_net_version >= 6) { null_check = is_not_null ? "!" : " ?? Array.Empty<byte>()"; } return ".ToArray()" + null_check; } else { - if( use_net6_features) { + if( target_net_version >= 6) { null_check = is_not_null ? "!" : " ?? string.Empty"; } return null_check; // simple assignment will do, strings are immutable in C# @@ -3448,23 +3524,25 @@ string t_netstd_generator::get_deep_copy_method_call(t_type* ttype, bool is_not_ } else if (is_union_enabled() && ttype->is_struct() && static_cast<t_struct*>(ttype)->is_union()) { - needs_typecast = (! ttype->is_container()); + needs_typecast = (! ttype->is_container()); suffix = nullable_suffix(); - if( use_net6_features) { + if( target_net_version >= 6) { null_check = is_not_null ? "!" : " ?? new "+ttype->get_name() +".___undefined()"; - } + } return "." + DEEP_COPY_METHOD_NAME + "()" + null_check; } else { - needs_typecast = (! ttype->is_container()); + needs_typecast = (! ttype->is_container()); suffix = nullable_suffix(); - if( use_net6_features) { + if( (target_net_version >= 8) && ttype->is_container()) { + null_check = is_not_null ? "!" : " ?? []"; + } else if( target_net_version >= 6) { null_check = is_not_null ? "!" : " ?? new()"; - } + } return "." + DEEP_COPY_METHOD_NAME + "()" + null_check; } - + throw "UNEXPECTED TYPE IN get_deep_copy_method_call: " + ttype->get_name(); } @@ -3486,8 +3564,8 @@ string t_netstd_generator::declare_field(t_field* tfield, bool init, bool allow_ string t_netstd_generator::initialize_field(t_field* tfield) { t_type* ttype = tfield->get_type(); - ttype = resolve_typedef(ttype); - + ttype = resolve_typedef(ttype); + if (ttype->is_base_type() && field_has_default(tfield)) { std::ofstream dummy; @@ -3505,9 +3583,9 @@ string t_netstd_generator::initialize_field(t_field* tfield) case t_base_type::TYPE_VOID: throw "NO T_VOID CONSTRUCT"; case t_base_type::TYPE_STRING: - if(use_net6_features && field_is_required(tfield)) { + if((target_net_version >= 6) && field_is_required(tfield)) { if (ttype->is_binary()) { - return " = Array.Empty<byte>()"; + return target_net_version >= 8 ? "= []" : " = Array.Empty<byte>()"; } else { return " = string.Empty"; } @@ -3538,7 +3616,7 @@ string t_netstd_generator::initialize_field(t_field* tfield) } else if (ttype->is_container()) { - if(use_net6_features) { + if(target_net_version >= 6) { return " = new()"; } else { return " = new " + type_name(ttype) + "()"; @@ -3546,8 +3624,8 @@ string t_netstd_generator::initialize_field(t_field* tfield) } else if (ttype->is_struct()) { - t_struct* tstruct = static_cast<t_struct*>(ttype); - if(use_net6_features) { + t_struct* tstruct = static_cast<t_struct*>(ttype); + if(target_net_version >= 6) { if(tstruct->is_union()) { return " = new " + type_name(ttype) + ".___undefined()"; } else { @@ -3557,7 +3635,7 @@ string t_netstd_generator::initialize_field(t_field* tfield) return " = new " + type_name(ttype) + "()"; } } - + throw "UNEXPECTED TYPE IN initialize_field: " + ttype->get_name(); } @@ -3777,6 +3855,7 @@ THRIFT_REGISTER_GENERATOR( " union: Use new union typing, which includes a static read function for union types.\n" " pascal: Generate Pascal Case property names according to Microsoft naming convention.\n" " net6: Enable features that require net6 and C# 8 or higher.\n" + " net8: Enable features that require net8 and C# 12 or higher.\n" " no_deepcopy: Suppress generation of " + DEEP_COPY_METHOD_NAME + "() method.\n" " async_postfix: Append \"Async\" to all service methods (maintains compatibility with existing code).\n" ) diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.h b/compiler/cpp/src/thrift/generate/t_netstd_generator.h index f16f7d3ad..ff3cfb126 100644 --- a/compiler/cpp/src/thrift/generate/t_netstd_generator.h +++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.h @@ -154,12 +154,12 @@ public: protected: std::string autogen_comment() override { string comment = "/**\n"; - if( ! use_net6_features) { + if( target_net_version < 6) { comment += " * <auto-generated>\n"; } comment += " * " + autogen_summary() + "\n"; comment += " * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING\n"; - if( ! use_net6_features) { + if( target_net_version < 6) { comment += " * </auto-generated>\n"; } comment += " */\n"; @@ -177,7 +177,7 @@ private: bool wcf_; bool use_pascal_case_properties; bool suppress_deepcopy; - bool use_net6_features; + int target_net_version; // 0 = any, 6 = net6, 8 = net8 bool add_async_postfix; const std::string CSHARP_KEYWORDS[101] = { diff --git a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj index b5afef582..cc2360de7 100644 --- a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj +++ b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj @@ -20,7 +20,8 @@ <PropertyGroup> <OutputType>Exe</OutputType> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <TieredCompilation>false</TieredCompilation> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <Nullable>enable</Nullable> diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj index 98e800775..3f52a5fe0 100644 --- a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj +++ b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj @@ -19,7 +19,8 @@ --> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <AssemblyName>Thrift.IntegrationTests</AssemblyName> <PackageId>Thrift.IntegrationTests</PackageId> <Version>0.20.0.0</Version> diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj index 6f3abb155..ecde36689 100644 --- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj +++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj @@ -21,7 +21,8 @@ <PropertyGroup> <ThriftVersion>0.20.0</ThriftVersion> <ThriftVersionOutput>Thrift version $(ThriftVersion)</ThriftVersionOutput> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <Version>$(ThriftVersion).0</Version> <AssemblyName>Thrift.PublicInterfaces.Compile.Tests</AssemblyName> <PackageId>Thrift.PublicInterfaces.Compile.Tests</PackageId> @@ -68,14 +69,14 @@ <Error Condition="$('$(ThriftBinaryVersion)'::StartsWith('$(ThriftVersionOutput)')) == true" Text="Thrift version returned: '$(ThriftBinaryVersion)' is not equal to the projects version '$(ThriftVersionOutput)'." /> <Message Importance="high" Text="Generating tests with thrift binary: '$(PathToThrift)'" /> <!-- Generate the thrift test files --> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./CassandraTest.thrift" /> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./optional_required_default.thrift" /> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./name_conflicts.thrift" /> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./../../../../test/ThriftTest.thrift" /> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./../../../../contrib/fb303/if/fb303.thrift" /> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./Thrift5253.thrift" /> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./Thrift5320.thrift" /> - <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net6 -r ./Thrift5382.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./CassandraTest.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./optional_required_default.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./name_conflicts.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./../../../../test/ThriftTest.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./../../../../contrib/fb303/if/fb303.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./Thrift5253.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./Thrift5320.thrift" /> + <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial,net8 -r ./Thrift5382.thrift" /> </Target> </Project> diff --git a/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs b/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs index 49108d187..c6cd22d4f 100644 --- a/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs +++ b/lib/netstd/Tests/Thrift.Tests/Collections/TCollectionsTests.cs @@ -56,8 +56,8 @@ namespace Thrift.Tests.Collections [TestMethod] public void TCollection_List_Equals_Objects_Test() { - var collection1 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } }; - var collection2 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } }; + var collection1 = new List<ExampleClass> { new() { X = 1 }, new() { X = 2 } }; + var collection2 = new List<ExampleClass> { new() { X = 1 }, new() { X = 2 } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } @@ -65,8 +65,8 @@ namespace Thrift.Tests.Collections [TestMethod] public void TCollection_List_List_Equals_Objects_Test() { - var collection1 = new List<List<ExampleClass>> { new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } } }; - var collection2 = new List<List<ExampleClass>> { new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } } }; + var collection1 = new List<List<ExampleClass>> { new() { new() { X = 1 }, new() { X = 2 } } }; + var collection2 = new List<List<ExampleClass>> { new() { new() { X = 1 }, new() { X = 2 } } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); // SequenceEqual() calls Equals() of the inner list instead of SequenceEqual() } @@ -74,7 +74,7 @@ namespace Thrift.Tests.Collections [TestMethod] public void TCollection_List_Equals_OneAndTheSameObject_Test() { - var collection1 = new List<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } }; + var collection1 = new List<ExampleClass> { new() { X = 1 }, new() { X = 2 } }; var collection2 = collection1; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); @@ -105,8 +105,8 @@ namespace Thrift.Tests.Collections [TestMethod] public void TCollection_Set_Equals_Objects_Test() { - var collection1 = new HashSet<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } }; - var collection2 = new HashSet<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } }; + var collection1 = new HashSet<ExampleClass> { new() { X = 1 }, new() { X = 2 } }; + var collection2 = new HashSet<ExampleClass> { new() { X = 1 }, new() { X = 2 } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); } @@ -114,8 +114,8 @@ namespace Thrift.Tests.Collections [TestMethod] public void TCollection_Set_Set_Equals_Objects_Test() { - var collection1 = new HashSet<HashSet<ExampleClass>> { new HashSet<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } } }; - var collection2 = new HashSet<HashSet<ExampleClass>> { new HashSet<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } } }; + var collection1 = new HashSet<HashSet<ExampleClass>> { new() { new() { X = 1 }, new() { X = 2 } } }; + var collection2 = new HashSet<HashSet<ExampleClass>> { new() { new() { X = 1 }, new() { X = 2 } } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsFalse(collection1.SequenceEqual(collection2)); // SequenceEqual() calls Equals() of the inner list instead of SequenceEqual() } @@ -123,7 +123,7 @@ namespace Thrift.Tests.Collections [TestMethod] public void TCollection_Set_Equals_OneAndTheSameObject_Test() { - var collection1 = new HashSet<ExampleClass> { new ExampleClass { X = 1 }, new ExampleClass { X = 2 } }; + var collection1 = new HashSet<ExampleClass> { new() { X = 1 }, new() { X = 2 } }; var collection2 = collection1; // references to one and the same collection Assert.IsTrue(TCollections.Equals(collection1, collection2)); Assert.IsTrue(collection1.SequenceEqual(collection2)); @@ -160,13 +160,13 @@ namespace Thrift.Tests.Collections { var collection1 = new Dictionary<int, ExampleClass> { - [1] = new ExampleClass { X = 1 }, - [-1] = new ExampleClass { X = 2 } + [1] = new() { X = 1 }, + [-1] = new() { X = 2 } }; var collection2 = new Dictionary<int, ExampleClass> { - [1] = new ExampleClass { X = 1 }, - [-1] = new ExampleClass { X = 2 } + [1] = new() { X = 1 }, + [-1] = new() { X = 2 } }; Assert.IsTrue(TCollections.Equals(collection1, collection2)); @@ -180,16 +180,16 @@ namespace Thrift.Tests.Collections { [0] = new Dictionary<int, ExampleClass> { - [1] = new ExampleClass { X = 1 }, - [-1] = new ExampleClass { X = 2 } + [1] = new() { X = 1 }, + [-1] = new() { X = 2 } } }; var collection2 = new Dictionary<int, Dictionary<int, ExampleClass>> { [0] = new Dictionary<int, ExampleClass> { - [1] = new ExampleClass { X = 1 }, - [-1] = new ExampleClass { X = 2 } + [1] = new() { X = 1 }, + [-1] = new() { X = 2 } } }; @@ -202,8 +202,8 @@ namespace Thrift.Tests.Collections { var collection1 = new Dictionary<int, ExampleClass> { - [1] = new ExampleClass { X = 1 }, - [-1] = new ExampleClass { X = 2 } + [1] = new() { X = 1 }, + [-1] = new() { X = 2 } }; var collection2 = collection1; Assert.IsTrue(TCollections.Equals(collection1, collection2)); diff --git a/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs b/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs index 11b5af4ee..7a43ca867 100644 --- a/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs +++ b/lib/netstd/Tests/Thrift.Tests/DataModel/DeepCopy.cs @@ -59,7 +59,7 @@ namespace Thrift.Tests.DataModel return instance; } - private jack? MakeNestedUnion(int nesting) + private jack.nested_struct? MakeNestedUnion(int nesting) { if (++nesting > 1) return null; @@ -148,14 +148,14 @@ namespace Thrift.Tests.DataModel if (nesting < 2) { - instance.Far_list = new List<Distance>() { Distance.foo, Distance.bar, Distance.baz }; - instance.Far_set = new HashSet<Distance>() { Distance.foo, Distance.bar, Distance.baz }; - instance.Far_map = new Dictionary<Distance, Distance>() { [Distance.foo] = Distance.foo, [Distance.bar] = Distance.bar, [Distance.baz] = Distance.baz }; + instance.Far_list = [Distance.foo, Distance.bar, Distance.baz]; + instance.Far_set = [Distance.foo, Distance.bar, Distance.baz]; + instance.Far_map = new() { [Distance.foo] = Distance.foo, [Distance.bar] = Distance.bar, [Distance.baz] = Distance.baz }; - instance.Far_set_list = new HashSet<List<Distance>>() { new List<Distance>() { Distance.foo } }; - instance.Far_list_map_set = new List<Dictionary<sbyte, HashSet<Distance>>>() { new Dictionary<sbyte, HashSet<Distance>>() { [1] = new HashSet<Distance>() { Distance.baz } } }; + instance.Far_set_list = [[Distance.foo]]; + instance.Far_list_map_set = [new Dictionary<sbyte, HashSet<Distance>>() { [1] = [Distance.baz] }]; - instance.Far_map_dist_to_rds = new Dictionary<Distance, List<RaceDetails>>() { [Distance.bar] = new List<RaceDetails>() }; + instance.Far_map_dist_to_rds = new() { [Distance.bar] = [] }; var details = MakeNestedRaceDetails(nesting); if (details != null) instance.Far_map_dist_to_rds[Distance.bar].Add(details); @@ -265,8 +265,7 @@ namespace Thrift.Tests.DataModel if (++level > 4) return value; - if (value == null) - value = MakeNestedUnion(0); + value ??= MakeNestedUnion(0); Debug.Assert(value?.As_nested_struct != null); ModifyInstance(value.As_nested_struct, level); return value; @@ -277,23 +276,21 @@ namespace Thrift.Tests.DataModel if (++level > 4) return value; - if (value == null) - value = new RaceDetails(); + value ??= new RaceDetails(); ModifyInstance(value,level); return value; } private Dictionary<Distance, List<RaceDetails>> ModifyValue(Dictionary<Distance, List<RaceDetails>>? value, int level) { - if (value == null) - value = new Dictionary<Distance, List<RaceDetails>>(); + value ??= []; if (++level > 4) return value; var details = new RaceDetails(); InitializeInstance(details); - value[Distance.foo] = new List<RaceDetails>() { details }; + value[Distance.foo] = [details]; if (value.TryGetValue(Distance.bar, out var list) && (list.Count > 0)) { @@ -309,17 +306,16 @@ namespace Thrift.Tests.DataModel private static List<Dictionary<sbyte, HashSet<Distance>>> ModifyValue(List<Dictionary<sbyte, HashSet<Distance>>>? value) { - if (value == null) - value = new List<Dictionary<sbyte, HashSet<Distance>>>(); + value ??= []; if (value.Count == 0) - value.Add(new Dictionary<sbyte, HashSet<Distance>>()); + value.Add([]); //else //value.Add(null); --Thrift does not allow null values in containers sbyte key = (sbyte)(value[0].Count + 10); if (value[0].Count == 0) - value[0].Add(key, new HashSet<Distance>()); + value[0].Add(key, []); //else //value[0].Add(key, null); --Thrift does not allow null values in containers @@ -331,9 +327,7 @@ namespace Thrift.Tests.DataModel { if (pair.Value != null) { - if (pair.Value.Contains(Distance.baz)) - pair.Value.Remove(Distance.baz); - else + if (!pair.Value.Remove(Distance.baz)) pair.Value.Add(Distance.baz); } } @@ -345,25 +339,22 @@ namespace Thrift.Tests.DataModel private static HashSet<List<Distance>> ModifyValue(HashSet<List<Distance>>? value) { - if (value == null) - value = new HashSet<List<Distance>>(); + value ??= []; if (value.Count == 0) - value.Add(new List<Distance>()); + value.Add([]); //else //value.Add(null); -- Thrift does not allow null values in containers foreach (var entry in value) - if( entry != null) - entry.Add(Distance.baz); + entry?.Add(Distance.baz); return value; } private static Dictionary<Distance, Distance> ModifyValue(Dictionary<Distance, Distance>? value) { - if (value == null) - value = new Dictionary<Distance, Distance>(); + value ??= []; value[Distance.foo] = value.ContainsKey(Distance.foo) ? ++value[Distance.foo] : Distance.foo; value[Distance.bar] = value.ContainsKey(Distance.bar) ? ++value[Distance.bar] : Distance.bar; value[Distance.baz] = value.ContainsKey(Distance.baz) ? ++value[Distance.baz] : Distance.baz; @@ -372,22 +363,15 @@ namespace Thrift.Tests.DataModel private static HashSet<Distance> ModifyValue(HashSet<Distance>? value) { - if (value == null) - value = new HashSet<Distance>(); + value ??= []; - if (value.Contains(Distance.foo)) - value.Remove(Distance.foo); - else + if (!value.Remove(Distance.foo)) value.Add(Distance.foo); - if (value.Contains(Distance.bar)) - value.Remove(Distance.bar); - else + if (!value.Remove(Distance.bar)) value.Add(Distance.bar); - if (value.Contains(Distance.baz)) - value.Remove(Distance.baz); - else + if (!value.Remove(Distance.baz)) value.Add(Distance.baz); return value; @@ -395,8 +379,7 @@ namespace Thrift.Tests.DataModel private static List<Distance> ModifyValue(List<Distance>? value) { - if (value == null) - value = new List<Distance>(); + value ??= []; value.Add(Distance.foo); value.Add(Distance.bar); value.Add(Distance.baz); @@ -410,36 +393,32 @@ namespace Thrift.Tests.DataModel private static Dictionary<sbyte, short> ModifyValue(Dictionary<sbyte, short>? value) { - if (value == null) - value = new Dictionary<sbyte, short>(); + value ??= []; value.Add((sbyte)(value.Count + 10), (short)value.Count); return value; } private static HashSet<long> ModifyValue(HashSet<long>? value) { - if (value == null) - value = new HashSet<long>(); + value ??= []; value.Add(value.Count+100); return value; } private static List<int> ModifyValue(List<int>? value) { - if (value == null) - value = new List<int>(); + value ??= []; value.Add(value.Count); return value; } private static byte[] ModifyValue(byte[]? value) { - if (value == null) - value = new byte[1] { 0 }; + value ??= [0]; if (value.Length > 0) value[0] = (value[0] < 0xFF) ? ++value[0] : (byte)0; else - value = new byte[1] { 0 }; + value = [0]; return value; } diff --git a/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs b/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs index 80eacc258..09f725140 100644 --- a/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs +++ b/lib/netstd/Tests/Thrift.Tests/DataModel/NullValuesSet.cs @@ -25,6 +25,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using OptReqDefTest; using Thrift.Collections; +#pragma warning disable IDE0079 // net20 - unneeded suppression #pragma warning disable IDE0017 // init can be simplified - we don't want that here namespace Thrift.Tests.DataModel diff --git a/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs index 6d391516e..03e3efa70 100644 --- a/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs +++ b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolHelperTests.cs @@ -1,4 +1,4 @@ -// Licensed to the Apache Software Foundation(ASF) under one +// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file @@ -34,17 +34,17 @@ namespace Thrift.Tests.Protocols // input/output var sets = new List<Tuple<TType, byte[]>> { - new Tuple<TType, byte[]>(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool), - new Tuple<TType, byte[]>(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte), - new Tuple<TType, byte[]>(TType.I16, TJSONProtocolConstants.TypeNames.NameI16), - new Tuple<TType, byte[]>(TType.I32, TJSONProtocolConstants.TypeNames.NameI32), - new Tuple<TType, byte[]>(TType.I64, TJSONProtocolConstants.TypeNames.NameI64), - new Tuple<TType, byte[]>(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble), - new Tuple<TType, byte[]>(TType.String, TJSONProtocolConstants.TypeNames.NameString), - new Tuple<TType, byte[]>(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct), - new Tuple<TType, byte[]>(TType.Map, TJSONProtocolConstants.TypeNames.NameMap), - new Tuple<TType, byte[]>(TType.Set, TJSONProtocolConstants.TypeNames.NameSet), - new Tuple<TType, byte[]>(TType.List, TJSONProtocolConstants.TypeNames.NameList), + new(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool), + new(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte), + new(TType.I16, TJSONProtocolConstants.TypeNames.NameI16), + new(TType.I32, TJSONProtocolConstants.TypeNames.NameI32), + new(TType.I64, TJSONProtocolConstants.TypeNames.NameI64), + new(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble), + new(TType.String, TJSONProtocolConstants.TypeNames.NameString), + new(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct), + new(TType.Map, TJSONProtocolConstants.TypeNames.NameMap), + new(TType.Set, TJSONProtocolConstants.TypeNames.NameSet), + new(TType.List, TJSONProtocolConstants.TypeNames.NameList), }; foreach (var t in sets) @@ -73,17 +73,17 @@ namespace Thrift.Tests.Protocols // input/output var sets = new List<Tuple<TType, byte[]>> { - new Tuple<TType, byte[]>(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool), - new Tuple<TType, byte[]>(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte), - new Tuple<TType, byte[]>(TType.I16, TJSONProtocolConstants.TypeNames.NameI16), - new Tuple<TType, byte[]>(TType.I32, TJSONProtocolConstants.TypeNames.NameI32), - new Tuple<TType, byte[]>(TType.I64, TJSONProtocolConstants.TypeNames.NameI64), - new Tuple<TType, byte[]>(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble), - new Tuple<TType, byte[]>(TType.String, TJSONProtocolConstants.TypeNames.NameString), - new Tuple<TType, byte[]>(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct), - new Tuple<TType, byte[]>(TType.Map, TJSONProtocolConstants.TypeNames.NameMap), - new Tuple<TType, byte[]>(TType.Set, TJSONProtocolConstants.TypeNames.NameSet), - new Tuple<TType, byte[]>(TType.List, TJSONProtocolConstants.TypeNames.NameList), + new(TType.Bool, TJSONProtocolConstants.TypeNames.NameBool), + new(TType.Byte, TJSONProtocolConstants.TypeNames.NameByte), + new(TType.I16, TJSONProtocolConstants.TypeNames.NameI16), + new(TType.I32, TJSONProtocolConstants.TypeNames.NameI32), + new(TType.I64, TJSONProtocolConstants.TypeNames.NameI64), + new(TType.Double, TJSONProtocolConstants.TypeNames.NameDouble), + new(TType.String, TJSONProtocolConstants.TypeNames.NameString), + new(TType.Struct, TJSONProtocolConstants.TypeNames.NameStruct), + new(TType.Map, TJSONProtocolConstants.TypeNames.NameMap), + new(TType.Set, TJSONProtocolConstants.TypeNames.NameSet), + new(TType.List, TJSONProtocolConstants.TypeNames.NameList), }; foreach (var t in sets) @@ -96,21 +96,21 @@ namespace Thrift.Tests.Protocols [ExpectedException(typeof(TProtocolException))] public void GetTypeIdForTypeName_TStopTypeName_Test() { - TJSONProtocolHelper.GetTypeIdForTypeName(new []{(byte)TType.Stop, (byte)TType.Stop}); + TJSONProtocolHelper.GetTypeIdForTypeName([(byte)TType.Stop, (byte)TType.Stop]); } [TestMethod] [ExpectedException(typeof(TProtocolException))] public void GetTypeIdForTypeName_NonExistingTypeName_Test() { - TJSONProtocolHelper.GetTypeIdForTypeName(new byte[]{100}); + TJSONProtocolHelper.GetTypeIdForTypeName([100]); } [TestMethod] [ExpectedException(typeof(TProtocolException))] public void GetTypeIdForTypeName_EmptyName_Test() { - TJSONProtocolHelper.GetTypeIdForTypeName(new byte[] {}); + TJSONProtocolHelper.GetTypeIdForTypeName([]); } [TestMethod] @@ -169,4 +169,4 @@ namespace Thrift.Tests.Protocols } } } -} \ No newline at end of file +} diff --git a/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs index 4054a29f2..4f14ba792 100644 --- a/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs +++ b/lib/netstd/Tests/Thrift.Tests/Protocols/TJsonProtocolTests.cs @@ -51,12 +51,8 @@ namespace Thrift.Tests.Protocols Assert.IsTrue(result.WrappedReader.GetType().Name.Equals("LookaheadReader", StringComparison.OrdinalIgnoreCase)); } - private class TJSONProtocolWrapper : TJsonProtocol + private class TJSONProtocolWrapper(TTransport trans) : TJsonProtocol(trans) { - public TJSONProtocolWrapper(TTransport trans) : base(trans) - { - } - public object WrappedContext => Context; public object WrappedReader => Reader; public int WrappedRecursionDepth => RecursionDepth; diff --git a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj index 94b7b09c1..54ce1e89c 100644 --- a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj +++ b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj @@ -19,7 +19,8 @@ --> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <Version>0.20.0.0</Version> <Nullable>enable</Nullable> </PropertyGroup> diff --git a/lib/netstd/Thrift/.editorconfig b/lib/netstd/Thrift/.editorconfig index 54b698cf4..82ff4a360 100644 --- a/lib/netstd/Thrift/.editorconfig +++ b/lib/netstd/Thrift/.editorconfig @@ -2,3 +2,8 @@ # CS1591: missing XML comment for public element dotnet_diagnostic.CS1591.severity = silent + +# silence certain yet unfixed false positives for net8 +dotnet_diagnostic.IDE0290.severity = silent +dotnet_diagnostic.CA1510.severity = silent +dotnet_diagnostic.CA1513.severity = silent diff --git a/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs b/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs index 9759058b3..5fc1fda4e 100644 --- a/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs +++ b/lib/netstd/Thrift/Processor/TMultiplexedProcessor.cs @@ -23,6 +23,11 @@ using System.Threading.Tasks; using Thrift.Protocol; using Thrift.Protocol.Entities; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0028 // net8 - simplified collection init +#pragma warning disable IDE0300 // net8 - simplified collection init +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Processor { // ReSharper disable once InconsistentNaming @@ -30,8 +35,7 @@ namespace Thrift.Processor { //TODO: Localization - private readonly Dictionary<string, ITAsyncProcessor> _serviceProcessorMap = - new Dictionary<string, ITAsyncProcessor>(); + private readonly Dictionary<string, ITAsyncProcessor> _serviceProcessorMap = new Dictionary<string, ITAsyncProcessor>(); public async Task<bool> ProcessAsync(TProtocol iprot, TProtocol oprot) { diff --git a/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs b/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs index 97ecff65c..568a50c51 100644 --- a/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs +++ b/lib/netstd/Thrift/Processor/TSingletonProcessorFactory.cs @@ -1,4 +1,4 @@ -// Licensed to the Apache Software Foundation(ASF) under one +// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file @@ -18,6 +18,9 @@ using Thrift.Server; using Thrift.Transport; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Processor { // ReSharper disable once InconsistentNaming @@ -35,4 +38,4 @@ namespace Thrift.Processor return _asyncProcessor; } } -} \ No newline at end of file +} diff --git a/lib/netstd/Thrift/Protocol/Entities/TField.cs b/lib/netstd/Thrift/Protocol/Entities/TField.cs index 4e29bb5d4..92fd41a8b 100644 --- a/lib/netstd/Thrift/Protocol/Entities/TField.cs +++ b/lib/netstd/Thrift/Protocol/Entities/TField.cs @@ -15,6 +15,9 @@ // specific language governing permissions and limitations // under the License. +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming @@ -34,4 +37,4 @@ namespace Thrift.Protocol.Entities // ReSharper disable once InconsistentNaming - do not rename - it used for generation public short ID { get; set; } } -} \ No newline at end of file +} diff --git a/lib/netstd/Thrift/Protocol/Entities/TList.cs b/lib/netstd/Thrift/Protocol/Entities/TList.cs index f59922564..7e5c5457b 100644 --- a/lib/netstd/Thrift/Protocol/Entities/TList.cs +++ b/lib/netstd/Thrift/Protocol/Entities/TList.cs @@ -15,6 +15,9 @@ // specific language governing permissions and limitations // under the License. +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming @@ -30,4 +33,4 @@ namespace Thrift.Protocol.Entities public int Count { get; set; } } -} \ No newline at end of file +} diff --git a/lib/netstd/Thrift/Protocol/Entities/TMap.cs b/lib/netstd/Thrift/Protocol/Entities/TMap.cs index 1efebe7a1..fba578097 100644 --- a/lib/netstd/Thrift/Protocol/Entities/TMap.cs +++ b/lib/netstd/Thrift/Protocol/Entities/TMap.cs @@ -15,6 +15,9 @@ // specific language governing permissions and limitations // under the License. +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming @@ -33,4 +36,4 @@ namespace Thrift.Protocol.Entities public int Count { get; set; } } -} \ No newline at end of file +} diff --git a/lib/netstd/Thrift/Protocol/Entities/TMessage.cs b/lib/netstd/Thrift/Protocol/Entities/TMessage.cs index 08d741d65..2e586ea68 100644 --- a/lib/netstd/Thrift/Protocol/Entities/TMessage.cs +++ b/lib/netstd/Thrift/Protocol/Entities/TMessage.cs @@ -15,6 +15,9 @@ // specific language governing permissions and limitations // under the License. +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming @@ -34,4 +37,4 @@ namespace Thrift.Protocol.Entities // ReSharper disable once InconsistentNaming - do not rename - it used for generation public int SeqID { get; set; } } -} \ No newline at end of file +} diff --git a/lib/netstd/Thrift/Protocol/Entities/TSet.cs b/lib/netstd/Thrift/Protocol/Entities/TSet.cs index 692d5642c..d29cc0db7 100644 --- a/lib/netstd/Thrift/Protocol/Entities/TSet.cs +++ b/lib/netstd/Thrift/Protocol/Entities/TSet.cs @@ -15,6 +15,9 @@ // specific language governing permissions and limitations // under the License. +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming @@ -35,4 +38,4 @@ namespace Thrift.Protocol.Entities public int Count { get; set; } } -} \ No newline at end of file +} diff --git a/lib/netstd/Thrift/Protocol/Entities/TStruct.cs b/lib/netstd/Thrift/Protocol/Entities/TStruct.cs index d87608799..b2fd00060 100644 --- a/lib/netstd/Thrift/Protocol/Entities/TStruct.cs +++ b/lib/netstd/Thrift/Protocol/Entities/TStruct.cs @@ -15,6 +15,9 @@ // specific language governing permissions and limitations // under the License. +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Protocol.Entities { // ReSharper disable once InconsistentNaming diff --git a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs index 7feb698b4..6389184a4 100644 --- a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs +++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs @@ -24,6 +24,8 @@ using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; using Thrift.Transport; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol { @@ -33,8 +35,8 @@ namespace Thrift.Protocol protected const uint VersionMask = 0xffff0000; protected const uint Version1 = 0x80010000; - protected bool StrictRead; - protected bool StrictWrite; + protected readonly bool StrictRead; + protected readonly bool StrictWrite; // minimize memory allocations by means of an preallocated bytes buffer // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long) @@ -470,15 +472,10 @@ namespace Thrift.Protocol public class Factory : TProtocolFactory { - protected bool StrictRead; - protected bool StrictWrite; + protected readonly bool StrictRead; + protected readonly bool StrictWrite; - public Factory() - : this(false, true) - { - } - - public Factory(bool strictRead, bool strictWrite) + public Factory(bool strictRead = false, bool strictWrite = true) { StrictRead = strictRead; StrictWrite = strictWrite; diff --git a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs index dd38f4870..8e5d00d14 100644 --- a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs +++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs @@ -27,6 +27,8 @@ using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; using Thrift.Transport; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0301 // net8 - simplified collection init namespace Thrift.Protocol { diff --git a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs index 9f761aeae..64308d60b 100644 --- a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs +++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs @@ -27,6 +27,8 @@ using Thrift.Protocol.Entities; using Thrift.Protocol.Utilities; using Thrift.Transport; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Protocol { diff --git a/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs b/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs index fbc8c05cc..510dc28af 100644 --- a/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs +++ b/lib/netstd/Thrift/Protocol/TMultiplexedProtocol.cs @@ -19,6 +19,9 @@ using System.Threading; using System.Threading.Tasks; using Thrift.Protocol.Entities; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Protocol { /** diff --git a/lib/netstd/Thrift/Protocol/ToString.cs b/lib/netstd/Thrift/Protocol/ToString.cs index ae69d1cb9..9a94c0813 100644 --- a/lib/netstd/Thrift/Protocol/ToString.cs +++ b/lib/netstd/Thrift/Protocol/ToString.cs @@ -34,16 +34,16 @@ namespace Thrift.Protocol sb.Append(", "); bool first_child = true; - if (self is string) // string is IEnumerable + if (self is string str) // string is IEnumerable { sb.Append('"'); - sb.Append(self); + sb.Append(str); sb.Append('"'); } - else if (self is IDictionary) + else if (self is IDictionary dict) { sb.Append("{ "); - foreach (DictionaryEntry pair in (self as IDictionary)) + foreach (DictionaryEntry pair in dict) { if (first_child) first_child = false; @@ -58,23 +58,23 @@ namespace Thrift.Protocol } sb.Append('}'); } - else if (self is IEnumerable) + else if (self is IEnumerable enumerable) { sb.Append("{ "); - foreach (var elm in (self as IEnumerable)) + foreach (var elm in enumerable) { elm.ToString(sb, first_child); first_child = false; } sb.Append('}'); } - else if (self is TBase) + else if (self is TBase tbase) { - sb.Append((self as TBase).ToString()); + sb.Append(tbase.ToString()); } - else if (self is double) + else if (self is double dbVal) { - sb.Append(((double)self).ToString(CultureInfo.InvariantCulture)); + sb.Append(dbVal.ToString(CultureInfo.InvariantCulture)); } else { diff --git a/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs b/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs index 90b8f8867..15ef04faf 100644 --- a/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs +++ b/lib/netstd/Thrift/Protocol/Utilities/TBase64Utils.cs @@ -17,6 +17,12 @@ using System; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0300 // net8 - simplified collection init +#pragma warning disable IDE0028 // net8 - simplified collection init +#pragma warning disable CA1510 // net8 - use ThrowIfNull +#pragma warning disable CA1513 // net8 - use ThrowIfNull + namespace Thrift.Protocol.Utilities { // ReSharper disable once InconsistentNaming @@ -98,4 +104,4 @@ namespace Thrift.Protocol.Utilities } } } -} \ No newline at end of file +} diff --git a/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs b/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs index 190ddbbc5..ecc026369 100644 --- a/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs +++ b/lib/netstd/Thrift/Protocol/Utilities/TGuidExtensions.cs @@ -42,9 +42,7 @@ namespace Thrift.Protocol.Utilities private static void SwapBytes(ref byte one, ref byte two) { - var tmp = one; - one = two; - two = tmp; + (two, one) = (one, two); } #region SelfTest diff --git a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs index f8c261aa8..6e248db8d 100644 --- a/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs +++ b/lib/netstd/Thrift/Protocol/Utilities/TJsonProtocolConstants.cs @@ -15,6 +15,9 @@ // specific language governing permissions and limitations // under the License. +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0300 // net8 - simplified collection init + namespace Thrift.Protocol.Utilities { // ReSharper disable once InconsistentNaming diff --git a/lib/netstd/Thrift/Server/TServer.cs b/lib/netstd/Thrift/Server/TServer.cs index 3d4f3fc20..5f5bc498c 100644 --- a/lib/netstd/Thrift/Server/TServer.cs +++ b/lib/netstd/Thrift/Server/TServer.cs @@ -65,8 +65,7 @@ namespace Thrift.Server // Log delegation? deprecated, use ILogger protected void LogError( string msg) { - if (Logger != null) - Logger.LogError("{Msg}",msg); // NOTE: Log message template, not string interpolation! + Logger?.LogError("{Msg}",msg); // NOTE: Log message template, not string interpolation! } public abstract void Stop(); diff --git a/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs b/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs index f1f6277d5..ffa3b8835 100644 --- a/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs +++ b/lib/netstd/Thrift/Server/TSimpleAsyncServer.cs @@ -23,6 +23,8 @@ using Thrift.Processor; using System.Threading.Tasks; using Microsoft.Extensions.Logging; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Server { diff --git a/lib/netstd/Thrift/Thrift.csproj b/lib/netstd/Thrift/Thrift.csproj index 2ebfb06df..c7b2a828e 100644 --- a/lib/netstd/Thrift/Thrift.csproj +++ b/lib/netstd/Thrift/Thrift.csproj @@ -19,7 +19,7 @@ --> <PropertyGroup> - <TargetFrameworks>netstandard2.1;netstandard2.0;net6.0;net7.0</TargetFrameworks> + <TargetFrameworks>netstandard2.1;netstandard2.0;net6.0;net7.0;net8.0</TargetFrameworks> <AssemblyName>Thrift</AssemblyName> <PackageId>ApacheThrift</PackageId> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> diff --git a/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs b/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs index bda129007..0a51c9a23 100644 --- a/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs +++ b/lib/netstd/Thrift/Transport/Client/TTlsSocketTransport.cs @@ -25,6 +25,9 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0028 // net8 - simplified collection init + namespace Thrift.Transport.Client { //TODO: check for correct work diff --git a/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs b/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs index 694ea0f40..5e67f10cd 100644 --- a/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs +++ b/lib/netstd/Thrift/Transport/Layered/TFramedTransport.cs @@ -21,6 +21,10 @@ using System.IO; using System.Threading; using System.Threading.Tasks; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable CA1510 // net8 - use ThrowIfNull +#pragma warning disable CA1513 // net8 - use ThrowIfNull + namespace Thrift.Transport { // ReSharper disable once InconsistentNaming diff --git a/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs b/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs index 98fbd227d..3d855a4f5 100644 --- a/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs +++ b/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs @@ -1,4 +1,4 @@ -// Licensed to the Apache Software Foundation(ASF) under one +// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file @@ -16,8 +16,9 @@ // under the License. using System; -using System.Collections.Generic; -using System.Text; + +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR namespace Thrift.Transport { diff --git a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs index b1ed91ef1..138c7fd9b 100644 --- a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs +++ b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs @@ -28,6 +28,11 @@ using System.Collections.Generic; using System.IO; using System.Diagnostics; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0028 // net8 - simplified collection init +#pragma warning disable IDE0300 // net8 - simplified collection init +#pragma warning disable IDE0290 // net8 - primary CTOR +#pragma warning disable SYSLIB1054 // net8 - use LibraryImport attribute #pragma warning disable CS1998 // async no await namespace Thrift.Transport.Server @@ -46,7 +51,7 @@ namespace Thrift.Transport.Server // to manage incoming connections, we set up a task for each stream to listen on private struct TaskStreamPair { - public NamedPipeServerStream Stream; + public readonly NamedPipeServerStream Stream; public Task Task; public TaskStreamPair(NamedPipeServerStream stream, Task task) @@ -321,8 +326,9 @@ namespace Thrift.Transport.Server // there must be an exact mapping between task index and stream index Debug.Assert(_streams.Count == tasks.Count); + #pragma warning disable IDE0305 // see https://github.com/dotnet/roslyn/issues/70656 - yet unsolved var index = Task.WaitAny(tasks.ToArray(), cancellationToken); - + #pragma warning restore IDE0305 var trans = new ServerTransport(_streams[index].Stream, Configuration); _streams.RemoveAt(index); // pass stream ownership to ServerTransport diff --git a/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs b/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs index 31ecef3aa..43663c3a7 100644 --- a/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs +++ b/lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs @@ -22,6 +22,9 @@ using System.Threading; using System.Threading.Tasks; using Thrift.Transport.Client; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Transport.Server { diff --git a/lib/netstd/Thrift/Transport/Server/TServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TServerTransport.cs index 5366114b0..70857c588 100644 --- a/lib/netstd/Thrift/Transport/Server/TServerTransport.cs +++ b/lib/netstd/Thrift/Transport/Server/TServerTransport.cs @@ -18,6 +18,9 @@ using System.Threading; using System.Threading.Tasks; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable IDE0290 // net8 - primary CTOR + namespace Thrift.Transport { // ReSharper disable once InconsistentNaming @@ -40,14 +43,8 @@ namespace Thrift.Transport public async ValueTask<TTransport> AcceptAsync(CancellationToken cancellationToken = default) { - var transport = await AcceptImplementationAsync(cancellationToken); - - if (transport == null) - { - throw new TTransportException($"{nameof(AcceptImplementationAsync)} should not return null"); - } - - return transport; + return await AcceptImplementationAsync(cancellationToken) + ?? throw new TTransportException($"{nameof(AcceptImplementationAsync)} should not return null"); } } } diff --git a/lib/netstd/Thrift/Transport/TTransport.cs b/lib/netstd/Thrift/Transport/TTransport.cs index 2f87ca0be..442022492 100644 --- a/lib/netstd/Thrift/Transport/TTransport.cs +++ b/lib/netstd/Thrift/Transport/TTransport.cs @@ -1,4 +1,4 @@ -// Licensed to the Apache Software Foundation(ASF) under one +// Licensed to the Apache Software Foundation(ASF) under one // or more contributor license agreements.See the NOTICE file // distributed with this work for additional information // regarding copyright ownership.The ASF licenses this file @@ -21,6 +21,10 @@ using System.IO; using System.Threading; using System.Threading.Tasks; +#pragma warning disable IDE0079 // net20 - unneeded suppression +#pragma warning disable CA1510 // net8 - use ThrowIfNull +#pragma warning disable CA1513 // net8 - use ThrowIfNull + namespace Thrift.Transport { //TODO: think about client info diff --git a/test/netstd/Client/Client.csproj b/test/netstd/Client/Client.csproj index 1ae67fa40..0e1eaa3af 100644 --- a/test/netstd/Client/Client.csproj +++ b/test/netstd/Client/Client.csproj @@ -19,8 +19,8 @@ --> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <LangVersion>9.0</LangVersion> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <AssemblyName>Client</AssemblyName> <PackageId>Client</PackageId> <OutputType>Exe</OutputType> @@ -49,8 +49,8 @@ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true"> <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" /> </Exec> - <Exec Condition="Exists('$(PathToThrift)')" Command=""$(PathToThrift)" -out $(ProjectDir) -gen netstd:wcf,union,serial,net6 -r ./../../ThriftTest.thrift" /> - <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net6 -r ./../../ThriftTest.thrift" /> - <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net6 -r ./../../ThriftTest.thrift" /> + <Exec Condition="Exists('$(PathToThrift)')" Command=""$(PathToThrift)" -out $(ProjectDir) -gen netstd:wcf,union,serial,net8 -r ./../../ThriftTest.thrift" /> + <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net8 -r ./../../ThriftTest.thrift" /> + <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net8 -r ./../../ThriftTest.thrift" /> </Target> </Project> diff --git a/test/netstd/Client/Performance/PerformanceTests.cs b/test/netstd/Client/Performance/PerformanceTests.cs index 6ac3aed86..5262379a6 100644 --- a/test/netstd/Client/Performance/PerformanceTests.cs +++ b/test/netstd/Client/Performance/PerformanceTests.cs @@ -28,8 +28,6 @@ using System.Threading.Tasks; using System.Diagnostics; using Thrift.Transport; -#pragma warning disable CS1998 // no await in async method - namespace Client.Tests { public class PerformanceTests @@ -44,7 +42,7 @@ namespace Client.Tests internal static async Task<int> Execute() { var instance = new PerformanceTests(); - instance.ProtocolPeformanceTestAsync().Wait(); + await instance.ProtocolPeformanceTestAsync(); // debug only if (Debugger.IsAttached) @@ -101,7 +99,7 @@ namespace Client.Tests ; if (!Transport.IsOpen) - Transport.OpenAsync().Wait(); + await Transport.OpenAsync(); if (Activator.CreateInstance(typeof(T), Transport) is T instance) return instance; diff --git a/test/netstd/Client/TestClient.cs b/test/netstd/Client/TestClient.cs index 3bf2daaae..748671229 100644 --- a/test/netstd/Client/TestClient.cs +++ b/test/netstd/Client/TestClient.cs @@ -17,7 +17,6 @@ #pragma warning disable IDE0066 // switch expression #pragma warning disable IDE0057 // substring -#pragma warning disable CS1998 // no await in async method using System; using System.Collections.Generic; @@ -93,19 +92,19 @@ namespace ThriftTest } else if (args[i].StartsWith("--pipe=")) { - pipe = args[i].Substring(args[i].IndexOf("=") + 1); + pipe = args[i].Substring(args[i].IndexOf('=') + 1); transport = TransportChoice.NamedPipe; } else if (args[i].StartsWith("--host=")) { // check there for ipaddress - host = args[i].Substring(args[i].IndexOf("=") + 1); + host = args[i].Substring(args[i].IndexOf('=') + 1); if (transport != TransportChoice.TlsSocket) transport = TransportChoice.Socket; } else if (args[i].StartsWith("--port=")) { - port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1)); + port = int.Parse(args[i].Substring(args[i].IndexOf('=') + 1)); if (transport != TransportChoice.TlsSocket) transport = TransportChoice.Socket; } @@ -393,7 +392,7 @@ namespace ThriftTest Console.WriteLine(); } - public static async Task<int> Execute(List<string> args) + public static Task<int> Execute(List<string> args) { try { @@ -408,7 +407,7 @@ namespace ThriftTest Console.WriteLine("*** FAILED ***"); Console.WriteLine("Error while parsing arguments"); Console.WriteLine("{0} {1}\nStack:\n{2}", ex.GetType().Name, ex.Message, ex.StackTrace); - return ErrorUnknown; + return Task.FromResult(ErrorUnknown); } //issue tests on separate threads simultaneously @@ -432,14 +431,14 @@ namespace ThriftTest Task.WaitAll(tasks); Console.WriteLine("Total time: " + (DateTime.Now - start)); Console.WriteLine(); - return retcode; + return Task.FromResult(retcode); } catch (Exception outerEx) { Console.WriteLine("*** FAILED ***"); Console.WriteLine("Unexpected error"); Console.WriteLine(outerEx.Message + "\n" + outerEx.StackTrace); - return ErrorUnknown; + return Task.FromResult(ErrorUnknown); } } @@ -646,8 +645,8 @@ namespace ThriftTest var two = new CrazyNesting(); one.String_field = "crazy"; two.String_field = "crazy"; - one.Binary_field = new byte[] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF }; - two.Binary_field = new byte[10] { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF }; + one.Binary_field = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF]; + two.Binary_field = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0xFF]; if (typeof(CrazyNesting).GetMethod("Equals")?.DeclaringType == typeof(CrazyNesting)) { if (!one.Equals(two)) @@ -820,10 +819,7 @@ namespace ThriftTest I32_thing = 8, I64_thing = 8 }; - insane.Xtructs = new List<Xtruct> - { - truck - }; + insane.Xtructs = [ truck ]; Console.Write("testInsanity()"); var whoa = await client.testInsanity(insane, MakeTimeoutToken()); Console.Write(" = {"); diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj index 020b8d545..38a942a06 100644 --- a/test/netstd/Server/Server.csproj +++ b/test/netstd/Server/Server.csproj @@ -19,8 +19,8 @@ --> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <LangVersion>9.0</LangVersion> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <AssemblyName>Server</AssemblyName> <PackageId>Server</PackageId> <OutputType>Exe</OutputType> @@ -50,8 +50,8 @@ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true"> <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" /> </Exec> - <Exec Condition="Exists('$(PathToThrift)')" Command=""$(PathToThrift)" -out $(ProjectDir) -gen netstd:wcf,union,serial,net6 -r ./../../ThriftTest.thrift" /> - <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net6 -r ./../../ThriftTest.thrift" /> - <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net6 -r ./../../ThriftTest.thrift" /> + <Exec Condition="Exists('$(PathToThrift)')" Command=""$(PathToThrift)" -out $(ProjectDir) -gen netstd:wcf,union,serial,net8 -r ./../../ThriftTest.thrift" /> + <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net8 -r ./../../ThriftTest.thrift" /> + <Exec Condition="Exists('$(ProjectDir)/../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial,net8 -r ./../../ThriftTest.thrift" /> </Target> </Project> diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs index a540d1919..2dea41824 100644 --- a/test/netstd/Server/TestServer.cs +++ b/test/netstd/Server/TestServer.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Reflection.Metadata.Ecma335; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; using System.Text; @@ -36,7 +37,6 @@ using Thrift.Transport.Server; #pragma warning disable IDE0063 // using can be simplified, we don't #pragma warning disable IDE0057 // substr can be simplified, we don't -#pragma warning disable CS1998 // await missing namespace ThriftTest { @@ -83,12 +83,12 @@ namespace ThriftTest { if (args[i].StartsWith("--pipe=")) { - pipe = args[i].Substring(args[i].IndexOf("=") + 1); + pipe = args[i].Substring(args[i].IndexOf('=') + 1); transport = TransportChoice.NamedPipe; } else if (args[i].StartsWith("--port=")) { - port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1)); + port = int.Parse(args[i].Substring(args[i].IndexOf('=') + 1)); if(transport != TransportChoice.TlsSocket) transport = TransportChoice.Socket; } @@ -163,9 +163,8 @@ namespace ThriftTest public class TestServer { - #pragma warning disable CA2211 - public static int _clientID = -1; // use with Interlocked only! - #pragma warning restore CA2211 + private static int _clientID = -1; // use with Interlocked only! + public static int ClientID => Interlocked.Add(ref _clientID, 0); private static readonly TConfiguration Configuration = new(); @@ -181,10 +180,10 @@ namespace ThriftTest return Task.CompletedTask; } - public async Task<object?> CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken) + public Task<object?> CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken) { callCount++; - return null; + return Task.FromResult<object?>(null); } public Task DeleteContextAsync(object serverContext, TProtocol input, TProtocol output, CancellationToken cancellationToken) @@ -268,7 +267,7 @@ namespace ThriftTest public Task<byte[]> testBinary(byte[]? thing, CancellationToken cancellationToken) { logger.Invoke("testBinary({0} bytes)", thing?.Length ?? 0); - return Task.FromResult(thing ?? Array.Empty<byte>()); + return Task.FromResult(thing ?? []); } public Task<Guid> testUuid(Guid thing, CancellationToken cancellationToken) @@ -318,7 +317,7 @@ namespace ThriftTest } sb.Append("}})"); logger.Invoke(sb.ToString()); - return Task.FromResult(thing ?? new Dictionary<int, int>()); // null returns are not allowed in Thrift + return Task.FromResult(thing ?? []); // null returns are not allowed in Thrift } public Task<Dictionary<string, string>> testStringMap(Dictionary<string, string>? thing, CancellationToken cancellationToken) @@ -343,7 +342,7 @@ namespace ThriftTest } sb.Append("}})"); logger.Invoke(sb.ToString()); - return Task.FromResult(thing ?? new Dictionary<string, string>()); // null returns are not allowed in Thrift + return Task.FromResult(thing ?? []); // null returns are not allowed in Thrift } public Task<HashSet<int>> testSet(HashSet<int>? thing, CancellationToken cancellationToken) @@ -368,7 +367,7 @@ namespace ThriftTest } sb.Append("}})"); logger.Invoke(sb.ToString()); - return Task.FromResult(thing ?? new HashSet<int>()); // null returns are not allowed in Thrift + return Task.FromResult(thing ?? []); // null returns are not allowed in Thrift } public Task<List<int>> testList(List<int>? thing, CancellationToken cancellationToken) @@ -393,7 +392,7 @@ namespace ThriftTest } sb.Append("}})"); logger.Invoke(sb.ToString()); - return Task.FromResult(thing ?? new List<int>()); // null returns are not allowed in Thrift + return Task.FromResult(thing ?? []); // null returns are not allowed in Thrift } public Task<Numberz> testEnum(Numberz thing, CancellationToken cancellationToken) diff --git a/tutorial/netstd/Client/Client.csproj b/tutorial/netstd/Client/Client.csproj index ee0bc8284..994d6be7b 100644 --- a/tutorial/netstd/Client/Client.csproj +++ b/tutorial/netstd/Client/Client.csproj @@ -19,8 +19,8 @@ --> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <LangVersion>9.0</LangVersion> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <AssemblyName>Client</AssemblyName> <PackageId>Client</PackageId> <OutputType>Exe</OutputType> diff --git a/tutorial/netstd/Interfaces/Interfaces.csproj b/tutorial/netstd/Interfaces/Interfaces.csproj index ff7891e5b..5ff8d9fb9 100644 --- a/tutorial/netstd/Interfaces/Interfaces.csproj +++ b/tutorial/netstd/Interfaces/Interfaces.csproj @@ -19,7 +19,7 @@ --> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> + <TargetFramework>net6.0</TargetFramework> <AssemblyName>Interfaces</AssemblyName> <PackageId>Interfaces</PackageId> <Version>0.20.0.0</Version> diff --git a/tutorial/netstd/Server/Server.csproj b/tutorial/netstd/Server/Server.csproj index 9aa3bc6b7..c72ec88ce 100644 --- a/tutorial/netstd/Server/Server.csproj +++ b/tutorial/netstd/Server/Server.csproj @@ -19,8 +19,8 @@ --> <PropertyGroup> - <TargetFramework>net7.0</TargetFramework> - <LangVersion>9.0</LangVersion> + <TargetFramework>net8.0</TargetFramework> + <LangVersion>latestMajor</LangVersion> <AssemblyName>Server</AssemblyName> <PackageId>Server</PackageId> <OutputType>Exe</OutputType>