You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2021/11/19 18:45:36 UTC

[ignite] branch ignite-2.12 updated: IGNITE-15954 .NET: Fix dynamic assemblies handling in TypeResolver (#9574)

This is an automated email from the ASF dual-hosted git repository.

ptupitsyn pushed a commit to branch ignite-2.12
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/ignite-2.12 by this push:
     new 93f6fc8  IGNITE-15954 .NET: Fix dynamic assemblies handling in TypeResolver (#9574)
93f6fc8 is described below

commit 93f6fc85b96854f42447ae3fafb6a52acf26cabb
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Fri Nov 19 21:08:18 2021 +0300

    IGNITE-15954 .NET: Fix dynamic assemblies handling in TypeResolver (#9574)
    
    * Allow dynamic assemblies in `TypeResolver`.
    * Skip compiler-generated type names parsing in `TypeNameParser`.
    
    (cherry picked from commit 69a68ea3f3f9005648a329153ad8cdccdbb6e043)
---
 .../Binary/TypeNameParserTest.cs                   | 20 +++++++------
 .../Binary/TypeResolverTest.cs                     | 24 ++++++++++++++-
 .../Examples/ExamplesTestBase.cs                   | 14 +++++++--
 .../Impl/Binary/TypeNameParser.cs                  | 34 +++++++++++++---------
 .../Apache.Ignite.Core/Impl/Binary/TypeResolver.cs |  5 ----
 5 files changed, 67 insertions(+), 30 deletions(-)

diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs
index b58b8d4..b2882f9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeNameParserTest.cs
@@ -240,17 +240,19 @@ namespace Apache.Ignite.Core.Tests.Binary
         }
 
         [Test]
-        public void TestCompilerGeneratedTypes()
+        public void TestCompilerGeneratedTypes([Values(
+                @"Foo.Bar+<Abc-Def<System-String\,System-Byte\[\]>-Convert>d__0",
+                @"Foo.Bar+<Foo-Bar<Abc-Def<System-Byte\[\]>\,Abc-Def<System-String>>-Convert>d__4`1",
+                @"Program\+IFoo`2\[\[System.Int32\, System.Private.CoreLib\, Version=4.0.0.0\, Culture=neutral\, PublicKeyToken=567\]\,\[System.String\, System.Private.CoreLib\, Version=4.0.0.0\, Culture=neutral\, PublicKeyToken=123\]\]"
+                )]
+            string typeName)
         {
-            var res = TypeNameParser.Parse(
-                @"Foo.Bar+<Abc-Def<System-String\,System-Byte\[\]>-Convert>d__0");
+            var res = TypeNameParser.Parse(typeName);
 
-            Assert.AreEqual(@"<Abc-Def<System-String\,System-Byte\[\]>-Convert>d__0", res.GetName());
-
-            var res2 = TypeNameParser.Parse(
-                @"Foo.Bar+<Foo-Bar<Abc-Def<System-Byte\[\]>\,Abc-Def<System-String>>-Convert>d__4`1");
-
-            Assert.AreEqual(@"<Foo-Bar<Abc-Def<System-Byte\[\]>\,Abc-Def<System-String>>-Convert>d__4`1", res2.GetName());
+            Assert.AreEqual(typeName, res.GetName());
+            Assert.IsNull(res.GetAssemblyName());
+            Assert.IsNull(res.GetArray());
+            Assert.IsFalse(res.HasNamespace());
         }
 
         /// <summary>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs
index abe78c6..8f1616f 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/TypeResolverTest.cs
@@ -19,9 +19,10 @@ namespace Apache.Ignite.Core.Tests.Binary
 {
     using System;
     using System.Collections.Generic;
+    using System.Reflection;
+    using System.Reflection.Emit;
 #if !NETCOREAPP
     using System.Linq;
-    using System.Reflection;
 #endif
     using Apache.Ignite.Core.Binary;
     using Apache.Ignite.Core.Impl.Binary;
@@ -171,6 +172,27 @@ namespace Apache.Ignite.Core.Tests.Binary
                 resolver.ResolveType("TestGenericBinarizable`1[[TypeResolverTest]][]", nameMapper: mapper));
         }
 
+        /// <summary>
+        /// Tests that types from dynamic assemblies can be resolved.
+        /// </summary>
+        [Test]
+        public void TestDynamicallyGeneratedType()
+        {
+            var typeName = nameof(TestDynamicallyGeneratedType) + new Random().Next();
+
+            var assemblyName = new AssemblyName("DynamicAssembly1");
+            var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
+            var moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule1");
+            var typeAttributes = TypeAttributes.Public | TypeAttributes.Class;
+            var typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes);
+            var generatedType = typeBuilder.CreateType();
+
+            var resolver = new TypeResolver();
+            var resolvedType = resolver.ResolveType(typeName);
+
+            Assert.AreEqual(generatedType, resolvedType);
+        }
+
 #if !NETCOREAPP
         /// <summary>
         /// Tests loading a type from referenced assembly that is not yet loaded.
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs
index cd2cbb1..430ecde 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Examples/ExamplesTestBase.cs
@@ -35,6 +35,9 @@ namespace Apache.Ignite.Core.Tests.Examples
         /** */
         private TextWriter _oldOut;
 
+        /** */
+        private TextWriter _oldError;
+
         /// <summary>
         /// Sets up the test.
         /// </summary>
@@ -42,8 +45,13 @@ namespace Apache.Ignite.Core.Tests.Examples
         public void SetUp()
         {
             _oldOut = Console.Out;
+            _oldError = Console.Error;
+
             _outSb = new StringBuilder();
-            Console.SetOut(new StringWriter(_outSb));
+            var outWriter = new StringWriter(_outSb);
+
+            Console.SetOut(outWriter);
+            Console.SetError(outWriter);
         }
 
         /// <summary>
@@ -53,9 +61,11 @@ namespace Apache.Ignite.Core.Tests.Examples
         public void TearDown()
         {
             Console.SetOut(_oldOut);
+            Console.SetError(_oldError);
             Console.WriteLine(_outSb);
 
-            StringAssert.Contains(">>> Example finished, press any key to exit ...", GetOutput());
+            var output = GetOutput();
+            StringAssert.Contains(">>> Example finished, press any key to exit ...", output, output);
         }
 
         /// <summary>
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
index 53ba61b..f1216ac 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeNameParser.cs
@@ -56,12 +56,32 @@ namespace Apache.Ignite.Core.Impl.Binary
         }
 
         /// <summary>
+        /// Initializes a new instance of the <see cref="TypeNameParser" /> class.
+        /// </summary>
+        private TypeNameParser(string typeName)
+        {
+            _typeName = typeName;
+            NameStart = 0;
+            NameEnd = typeName.Length - 1;
+
+            AssemblyStart = -1;
+            AssemblyEnd = -1;
+            ArrayStart = -1;
+        }
+
+        /// <summary>
         /// Parses the specified type name.
         /// </summary>
         public static TypeNameParser Parse(string typeName)
         {
             IgniteArgumentCheck.NotNullOrEmpty(typeName, "typeName");
 
+            if (typeName.Contains("\\"))
+            {
+                // Do not parse compiler-generated special names, return as is.
+                return new TypeNameParser(typeName);
+            }
+
             int pos = 0;
 
             return new TypeNameParser(typeName, ref pos);
@@ -411,19 +431,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// </summary>
         private char Char
         {
-            get
-            {
-                const char escape = '\\';
-
-                if (_pos > 0 && _typeName[_pos - 1] == escape)
-                {
-                    // Ignore escaped characters in compiler-generated type names.
-                    // Return any non-separator character to continue parsing.
-                    return default;
-                }
-
-                return _typeName[_pos];
-            }
+            get { return _typeName[_pos]; }
         }
 
         /** <inheritdoc /> */
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
index b0c5206..cbeed1e 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/TypeResolver.cs
@@ -267,11 +267,6 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// </summary>
         private static Type FindType(Assembly asm, string typeName, IBinaryNameMapper mapper)
         {
-            if (asm.IsDynamic)
-            {
-                return null;
-            }
-
             if (mapper == null)
             {
                 return asm.GetType(typeName);