Esempio n. 1
0
        /// <summary>
        /// Asserts that the emitted IL for a type is the same as the expected IL.
        /// Many core library types are in different assemblies on .Net Framework, and .Net Core.
        /// Therefore this test is likely to fail unless you  only run it only only on one of these frameworks,
        /// or you run it on both, but provide a different expected output string for each.
        /// See <see cref="ExecutionConditionUtil"/>.
        /// </summary>
        /// <param name="typeName">The non-fully-qualified name of the type</param>
        /// <param name="expected">The expected IL</param>
        public void VerifyTypeIL(string typeName, string expected)
        {
            var output = new ICSharpCode.Decompiler.PlainTextOutput();

            using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies))
            {
                string             mainModuleFullName = Emit(testEnvironment, manifestResources: null, EmitOptions.Default);
                IList <ModuleData> moduleData         = testEnvironment.GetAllModuleData();
                var mainModule = moduleData.Single(md => md.FullName == mainModuleFullName);
                using (var moduleMetadata = ModuleMetadata.CreateFromImage(testEnvironment.GetMainImage()))
                {
                    var peFile         = new PEFile(mainModuleFullName, moduleMetadata.Module.PEReaderOpt);
                    var metadataReader = moduleMetadata.GetMetadataReader();

                    bool found = false;
                    foreach (var typeDefHandle in metadataReader.TypeDefinitions)
                    {
                        var typeDef = metadataReader.GetTypeDefinition(typeDefHandle);
                        if (metadataReader.GetString(typeDef.Name) == typeName)
                        {
                            var disassembler = new ICSharpCode.Decompiler.Disassembler.ReflectionDisassembler(output, default);
                            disassembler.DisassembleType(peFile, typeDefHandle);
                            found = true;
                            break;
                        }
                    }
                    Assert.True(found, "Could not find type named " + typeName);
                }
            }
            AssertEx.AssertEqualToleratingWhitespaceDifferences(expected, output.ToString(), escapeQuotes: false);
        }
Esempio n. 2
0
        public void Emit(string expectedOutput, int?expectedReturnCode, string[] args, IEnumerable <ResourceDescription> manifestResources, EmitOptions emitOptions, Verification peVerify, SignatureDescription[] expectedSignatures)
        {
            using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies))
            {
                string mainModuleName = Emit(testEnvironment, manifestResources, emitOptions);
                _allModuleData = testEnvironment.GetAllModuleData();

                if (peVerify == Verification.Passes)
                {
                    testEnvironment.PeVerify();
                }
                else if (peVerify == Verification.Fails)
                {
                    Assert.Throws <PeVerifyException>(() => testEnvironment.PeVerify());
                }

                if (expectedSignatures != null)
                {
                    MetadataSignatureUnitTestHelper.VerifyMemberSignatures(testEnvironment, expectedSignatures);
                }

                if (expectedOutput != null || expectedReturnCode != null)
                {
                    var returnCode = testEnvironment.Execute(mainModuleName, args, expectedOutput);

                    if (expectedReturnCode is int exCode)
                    {
                        Assert.Equal(exCode, returnCode);
                    }
                }
            }
        }
Esempio n. 3
0
        public void Emit(
            string expectedOutput,
            bool trimOutput,
            int?expectedReturnCode,
            string[] args,
            IEnumerable <ResourceDescription> manifestResources,
            EmitOptions emitOptions,
            Verification peVerify,
            SignatureDescription[] expectedSignatures)
        {
            using var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies);

            string mainModuleName = Emit(testEnvironment, manifestResources, emitOptions);

            _allModuleData = testEnvironment.GetAllModuleData();
            testEnvironment.Verify(peVerify);
#if NETCOREAPP
            ILVerify(peVerify);
#endif

            if (expectedSignatures != null)
            {
                MetadataSignatureUnitTestHelper.VerifyMemberSignatures(testEnvironment, expectedSignatures);
            }

            if (expectedOutput != null || expectedReturnCode != null)
            {
                var returnCode = testEnvironment.Execute(mainModuleName, args, expectedOutput, trimOutput);

                if (expectedReturnCode is int exCode)
                {
                    Assert.Equal(exCode, returnCode);
                }
            }
        }
Esempio n. 4
0
 // TODO(tomat): Fold into CompileAndVerify.
 // Replace bool verify parameter with string[] expectedPeVerifyOutput. If null, no verification. If empty verify have to succeed. Otherwise compare errors.
 public void EmitAndVerify(params string[] expectedPeVerifyOutput)
 {
     using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies))
     {
         string   mainModuleName = Emit(testEnvironment, null, null);
         string[] actualOutput   = testEnvironment.VerifyModules(new[] { mainModuleName });
         Assert.Equal(expectedPeVerifyOutput, actualOutput);
     }
 }
Esempio n. 5
0
        public string Dump()
        {
            using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies))
            {
                string             mainModuleFullName   = Emit(testEnvironment, manifestResources: null, EmitOptions.Default);
                IList <ModuleData> moduleDatas          = testEnvironment.GetAllModuleData();
                string             mainModuleSimpleName = moduleDatas.Single(md => md.FullName == mainModuleFullName).SimpleName;
                RuntimeEnvironmentUtilities.DumpAssemblyData(moduleDatas, out var dumpDir);

                string modulePath = Path.Combine(dumpDir, mainModuleSimpleName + ".dll");
                var    decompiler = new ICSharpCode.Decompiler.CSharp.CSharpDecompiler(modulePath, new ICSharpCode.Decompiler.DecompilerSettings());
                var    syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();
                return(syntaxTree.ToString());
            }
        }
Esempio n. 6
0
            public void Emit(string expectedOutput, IEnumerable <ResourceDescription> manifestResources, EmitOptions emitOptions, bool peVerify, SignatureDescription[] expectedSignatures)
            {
                using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies))
                {
                    string mainModuleName = Emit(testEnvironment, manifestResources, emitOptions);
                    _allModuleData = testEnvironment.GetAllModuleData();

                    if (peVerify)
                    {
                        testEnvironment.PeVerify();
                    }

                    if (expectedSignatures != null)
                    {
                        MetadataSignatureUnitTestHelper.VerifyMemberSignatures(testEnvironment, expectedSignatures);
                    }

                    if (expectedOutput != null)
                    {
                        testEnvironment.Execute(mainModuleName, expectedOutput);
                    }
                }
            }
Esempio n. 7
0
        public string Dump(string methodName = null)
        {
            using (var testEnvironment = RuntimeEnvironmentFactory.Create(_dependencies))
            {
                string             mainModuleFullName = Emit(testEnvironment, manifestResources: null, EmitOptions.Default);
                IList <ModuleData> moduleDatas        = testEnvironment.GetAllModuleData();
                var mainModule = moduleDatas.Single(md => md.FullName == mainModuleFullName);
                RuntimeEnvironmentUtilities.DumpAssemblyData(moduleDatas, out var dumpDir);

                string extension  = mainModule.Kind == OutputKind.ConsoleApplication ? ".exe" : ".dll";
                string modulePath = Path.Combine(dumpDir, mainModule.SimpleName + extension);

                var decompiler = new ICSharpCode.Decompiler.CSharp.CSharpDecompiler(modulePath,
                                                                                    new ICSharpCode.Decompiler.DecompilerSettings()
                {
                    AsyncAwait = false
                });

                if (methodName != null)
                {
                    var map = new Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod>();
                    listMethods(decompiler.TypeSystem.MainModule.RootNamespace, map);

                    if (map.TryGetValue(methodName, out var method))
                    {
                        return(decompiler.DecompileAsString(method.MetadataToken));
                    }
                    else
                    {
                        throw new Exception($"Didn't find method '{methodName}'. Available/distinguishable methods are: \r\n{string.Join("\r\n", map.Keys)}");
                    }
                }

                return(decompiler.DecompileWholeModuleAsString());
            }

            void listMethods(ICSharpCode.Decompiler.TypeSystem.INamespace @namespace, Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod> result)
            {
                foreach (var nestedNS in @namespace.ChildNamespaces)
                {
                    if (nestedNS.FullName != "System" &&
                        nestedNS.FullName != "Microsoft")
                    {
                        listMethods(nestedNS, result);
                    }
                }

                foreach (var type in @namespace.Types)
                {
                    listMethodsInType(type, result);
                }
            }

            void listMethodsInType(ICSharpCode.Decompiler.TypeSystem.ITypeDefinition type, Dictionary <string, ICSharpCode.Decompiler.TypeSystem.IMethod> result)
            {
                foreach (var nestedType in type.NestedTypes)
                {
                    listMethodsInType(nestedType, result);
                }

                foreach (var method in type.Methods)
                {
                    if (result.ContainsKey(method.FullName))
                    {
                        // There is a bug with FullName on methods in generic types
                        result.Remove(method.FullName);
                    }
                    else
                    {
                        result.Add(method.FullName, method);
                    }
                }
            }
        }