private WeakEventHandlerWeaver(ModuleDefinition moduleDefinition, ITypeSystem typeSystem, ILogger logger, TypeReference makeWeakAttributeReference)
        {
            _moduleDefinition = moduleDefinition;
            _typeSystem       = typeSystem;
            _logger           = logger;

            var makeWeakAttribute = makeWeakAttributeReference.Resolve();

            var helperTypes = makeWeakAttribute.Module.Types;

            _codeImporter = new CodeImporter(moduleDefinition)
            {
                NamespaceDecorator = value => "<>" + value
            };

            _weakAdapterType      = _codeImporter.Import(helperTypes.Single(t => t.Name == "WeakEventHandlerFodyWeakEventAdapter`4"));
            _eventTargetInterface = _codeImporter.Import(helperTypes.Single(t => t.Name == "IWeakEventHandlerFodyWeakEventTarget"));

            _weakAdapterConstructor = _weakAdapterType.GetConstructors().Single(ctor => ctor.Parameters.Count == 4);
            _generatedCodeAttribute = _weakAdapterType.CustomAttributes.Single(attr => attr.AttributeType.Name == nameof(GeneratedCodeAttribute));

            var weakAdapterMethods = _weakAdapterType.GetMethods().ToList();

            _weakAdapterSubscribeMethod   = weakAdapterMethods.Single(method => method.Name == "Subscribe");
            _weakAdapterUnsubscribeMethod = weakAdapterMethods.Single(method => method.Name == "Unsubscribe");
            _weakAdapterReleaseMethod     = weakAdapterMethods.Single(method => method.Name == "Release");

            _action2Type        = typeSystem.ImportType <Action <object, EventArgs> >();
            _action2Constructor = typeSystem.ImportMethod <Action <object, EventArgs>, object, IntPtr>(".ctor");
            _action3Type        = typeSystem.ImportType <Action <Type, object, EventArgs> >();
            _action3Constructor = typeSystem.ImportMethod <Action <Type, object, EventArgs>, object, IntPtr>(".ctor");
        }
Example #2
0
        public void OnGenericTypeTest1()
        {
            var module   = ModuleHelper.LoadModule <EmptyClass>();
            var importer = new CodeImporter(module)
            {
                CompactMode = false
            };

            var type   = importer.Import <SimpleSampleClass>();
            var method = importer.ImportMethod(() => default(SimpleGenericClass <T>) !.Method(default));
Example #3
0
        public void Update_UsingSourceAndDocsFolder_WillReturnCodeSnippetCount()
        {
            var directory = @"data\test-site\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");
            var result     = CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            Assert.Equal(14, result.Snippets);
        }
Example #4
0
        public void When_Code_Snippet_Defined_But_Not_Used_Returns_True()
        {
            var directory = @"data\validation\no-reference\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");

            var result = CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            Assert.True(result.Completed);
        }
Example #5
0
        public void When_Tag_Found_In_Docs_But_Not_Found_In_Code_Returns_False()
        {
            var directory = @"data\validation\no-snippets\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");

            var result = CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            Assert.False(result.Completed);
        }
        public void ImportMethodTest()
        {
            var module = ModuleHelper.LoadModule <EmptyClass>();

            var target = new CodeImporter(module)
            {
                CompactMode = false
            };

            var importedMethod1 = target.ImportMethod(() => default(MyEventArgs) !.GetValue());
            var importedMethod2 = target.ImportMethod(() => default(MyEventArgs) !.GetValue(default !));
Example #7
0
        public void When_Incomplete_Snippet_Found_Does_Not_Import()
        {
            var directory = @"data\validation\bad-snippet\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");

            var result = CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            Assert.False(result.Completed);
        }
Example #8
0
        static void Main()
        {
            var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;

            var assemblyPath = Path.Combine(baseDirectory, "ShellAssembly.exe");
            var module       = ModuleHelper.LoadModule(assemblyPath);

            var codeImporter = new CodeImporter(module)
            {
                HideImportedTypes = false,
                ModuleResolver    = new AssemblyModuleResolver(
                    typeof(Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialog).Assembly,
                    typeof(Microsoft.WindowsAPICodePack.Dialogs.TaskDialog).Assembly,
                    typeof(Newtonsoft.Json.JsonConvert).Assembly)
            };

            codeImporter.ILMerge();

            var tempPath = TestHelper.TempPath;

            var importedModules = codeImporter.ListImportedModules();

            foreach (var m in importedModules)
            {
                foreach (var resource in m.Resources.OfType <EmbeddedResource>())
                {
                    module.Resources.Add(resource);
                }
            }

            var targetAssemblyPath = Path.Combine(tempPath, "ShellAssembly2.exe");

            module.Assembly.Name.Name = "ShellAssembly2";
            var now = DateTime.Now;

            module.Assembly.Name.Version = new Version(now.Year, now.Month, now.Day, (int)now.TimeOfDay.TotalMilliseconds);
            module.Write(targetAssemblyPath);

            var peVerify = TestHelper.PEVerify.Verify(targetAssemblyPath, line => Console.WriteLine(line));

            Assert.True(peVerify);

            var importedTypes = codeImporter.ListImportedTypes();

            TestHelper.VerifyTypes(importedTypes, importedModules, targetAssemblyPath, AssertIl);

            var il = TestHelper.ILDasm.Decompile(targetAssemblyPath);

            File.WriteAllText(Path.ChangeExtension(targetAssemblyPath, ".il"), il);

            Console.WriteLine("Done - press any key...");
            Console.ReadKey();
        }
        public void ComplexTypesTest(int numberOfTypes, params Type[] types)
        {
            var module = ModuleHelper.LoadModule <EmptyClass>();

            var governingType = types.First();

            var target = new CodeImporter(module)
            {
                // else IL comparison will fail:
                HideImportedTypes = false,
                CompactMode       = false
            };

            foreach (var type in types)
            {
                target.Import(type);
            }

            var tempPath = TestHelper.TempPath;

            var targetAssemblyPath = Path.Combine(tempPath, "TargetAssembly2.dll");

            module.Write(targetAssemblyPath);

            var sourceAssemblyPath = Path.Combine(tempPath, "SourceAssembly2.dll");

            var sourceModule = ModuleHelper.LoadModule(new Uri(governingType.Assembly.CodeBase).LocalPath);

            sourceModule.Assembly.Name.Name = "SourceAssembly";
            sourceModule.Write(sourceAssemblyPath);

            var importedTypes = target.ListImportedTypes();

            if (importedTypes.Keys.Select(t => t.FullName).Contains("TomsToolbox.Core.NetStandardExtensions"))
            {
                numberOfTypes += 1;
            }

            foreach (var type in importedTypes)
            {
                _testOutputHelper.WriteLine(type.Key.FullName);
            }


            Assert.Equal(numberOfTypes, importedTypes.Count);

            TestHelper.VerifyTypes(importedTypes, target.ListImportedModules(), targetAssemblyPath);

            Assert.True(TestHelper.PEVerify.Verify(targetAssemblyPath, _testOutputHelper));
        }
Example #10
0
        public override void Execute()
        {
#if DEBUG && LAUNCH_DEBUGGER
            System.Diagnostics.Debugger.Launch();
#endif

            var includeAssemblies = BuildRegex(ReadConfigValue("IncludeAssemblies", string.Empty));
            var excludeAssemblies = BuildRegex(ReadConfigValue("ExcludeAssemblies", string.Empty));
            var includeResources  = BuildRegex(ReadConfigValue("IncludeResources", string.Empty));
            var excludeResources  = BuildRegex(ReadConfigValue("ExcludeResources", string.Empty));
            var hideImportedTypes = ReadConfigValue("HideImportedTypes", true);
            var namespacePrefix   = ReadConfigValue("NamespacePrefix", string.Empty);
            var compactMode       = ReadConfigValue("CompactMode", false);
            var fullImport        = ReadConfigValue("FullImport", false);

            var isDotNetCore = ModuleDefinition.IsTargetFrameworkDotNetCore();

            var references = isDotNetCore ? (IList <string>)References.Split(';') : ReferenceCopyLocalPaths;

            var codeImporter = new CodeImporter(ModuleDefinition)
            {
                ModuleResolver     = new LocalReferenceModuleResolver(this, references, includeAssemblies, excludeAssemblies),
                HideImportedTypes  = hideImportedTypes,
                NamespaceDecorator = name => namespacePrefix + name,
                CompactMode        = compactMode && !fullImport,
            };

            codeImporter.ILMerge();

            var importedModules = codeImporter.ListImportedModules();

            if (fullImport)
            {
                importedModules = ImportRemainingTypes(importedModules, codeImporter);
            }

            ValidateBamlReferences(ModuleDefinition, importedModules);

            ImportResources(ModuleDefinition, importedModules, includeResources, excludeResources, this);

            var importedReferences = new HashSet <string>(importedModules.Select(moduleDefinition => Path.GetFileNameWithoutExtension(moduleDefinition.FileName)), StringComparer.OrdinalIgnoreCase);

            bool IsImportedReference(string path)
            {
                return(importedReferences.Contains(Path.GetFileNameWithoutExtension(path)));
            }

            ReferenceCopyLocalPaths.RemoveAll(IsImportedReference);
            RuntimeCopyLocalPaths.RemoveAll(IsImportedReference);
        }
Example #11
0
        public void Update_UsingSourceAndDocsFolder_WillFormatWithCodeSnippet()
        {
            var directory = @"data\test-site\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");

            CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            var indexFile = Path.Combine(directory, @"docs\index.md");
            var actual    = File.ReadAllText(indexFile);

            var outputFile = Path.Combine(directory, @"output.md");
            var expected   = File.ReadAllText(outputFile);

            Assert.Equal(expected, actual);
        }
Example #12
0
        public void ProcessTheJsonDotNetDocs()
        {
            var directory = @"D:\Code\github\shiftkey\Newtonsoft.Json";

            var codeFolder = directory;
            var docsFolder = Path.Combine(directory, @"docs\");
            var result     = CodeImporter.Update(codeFolder, new[] { ".*Documentation.*Tests[.]cs" }, docsFolder);

            Console.WriteLine("Completed: {0}", result.Completed);
            Console.WriteLine("Duration: {0}ms", result.ElapsedMilliseconds);

            foreach (var message in result.Errors)
            {
                Console.WriteLine("Error: {0}", message);
            }

            foreach (var message in result.Warnings)
            {
                Console.WriteLine("Warning: {0}", message);
            }
        }
Example #13
0
        public void When_Incomplete_Snippet_Found_Displays_Error_Message()
        {
            var directory = @"data\validation\bad-snippet\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");

            var expectedFile = Path.Combine(codeFolder, "code.cs");

            var result = CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            var error = result.Errors.First();

            // message explains error
            Assert.Equal(error.Message, "Code snippet reference 'ThisIsAInvalidCodeSnippet' was not closed (specify 'end code ThisIsAInvalidCodeSnippet').");

            // file is as we expected
            Assert.Equal(error.File, expectedFile);

            // and we have the right line number to look at
            Assert.Equal(30, error.LineNumber);
        }
Example #14
0
        public void When_Code_Snippet_Defined_But_Not_Used_In_Docs_Displays_Warning_Message()
        {
            var directory = @"data\validation\no-reference\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");

            var expectedFile = Path.Combine(codeFolder, "code.cs");

            var result = CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            var warning = result.Warnings.First();

            // message explains error
            Assert.Equal(warning.Message, "Code snippet reference 'LinqToJsonCreateParse' is not used in any pages and can be removed");

            // file is as we expected
            Assert.Equal(warning.File, expectedFile);

            // and we have the right line number to look at
            Assert.Equal(32, warning.LineNumber);
        }
Example #15
0
        public void When_Tag_Found_In_Docs_But_Not_Found_In_Code_Display_Error()
        {
            var directory = @"data\validation\no-snippets\".ToCurrentDirectory();

            var codeFolder = Path.Combine(directory, @"source\");
            var docsFolder = Path.Combine(directory, @"docs\");

            var expectedFile = Path.Combine(docsFolder, "index.md");

            var result = CodeImporter.Update(codeFolder, new[] { "*.cs" }, docsFolder);

            var error = result.Errors.First();

            // message explains error
            Assert.Equal(error.Message, "Could not find a code snippet for reference 'LinqToJsonCreateParse'");

            // file is as we expected
            Assert.Equal(error.File, expectedFile);

            // and we have the right line number to look at
            Assert.Equal(15, error.LineNumber);
        }
        public void SimpleTypesTest(int numberOfTypes, ModuleResolver moduleResolver, params Type[] types)
        {
            var module = ModuleHelper.LoadModule <EmptyClass>();

            var moduleResolverInstance = moduleResolver == ModuleResolver.AssemblyModuleResolver
                ? (IModuleResolver) new AssemblyModuleResolver(typeof(TomsToolbox.Core.AssemblyExtensions).Assembly, typeof(TomsToolbox.Core.DefaultValue).Assembly)
                : new LocalReferenceModuleResolver();

            var targetAssemblyPath = Path.Combine(TestHelper.TempPath, "TargetAssembly1.dll");

            var target = new CodeImporter(module)
            {
                ModuleResolver    = moduleResolverInstance,
                HideImportedTypes = false,
                CompactMode       = false
            };

            foreach (var type in types)
            {
                target.Import(type);
            }

            module.Write(targetAssemblyPath);

            var importedTypes = target.ListImportedTypes();

            foreach (var type in importedTypes)
            {
                _testOutputHelper.WriteLine(type.Key.FullName);
            }

            var importedModules = target.ListImportedModules();

            Assert.True(TestHelper.PEVerify.Verify(targetAssemblyPath, _testOutputHelper));
            Assert.Equal(numberOfTypes, importedTypes.Count);

            TestHelper.VerifyTypes(importedTypes, importedModules, targetAssemblyPath);
        }
Example #17
0
        /// <summary>
        /// Create in-memory compilation of library
        /// </summary>
        private void CreateLibrary()
        {
            if (string.IsNullOrEmpty(_settings.LibraryRootDirectory) ||
                !Directory.Exists(_settings.LibraryRootDirectory))
            {
                return;
            }
            try
            {
                lock ( Sync )
                {
                    var builder = new CompilationBuilder();

                    // adding all *.cs files
                    foreach (var path in Directory.GetFiles(_settings.LibraryRootDirectory, "*.cs", SearchOption.AllDirectories))
                    {
                        builder.AddSourceFile(path);
                    }
                    _compilation = builder.Build();

                    var errors = builder.ValidateCompilation(_compilation);
                    if (errors != null && errors.Any())
                    {
                        MessageBox.Show("There were compilation errors of library: " + Environment.NewLine
                                        + string.Join(Environment.NewLine, errors));
                    }

                    _codeImporter = new CodeImporter(_compilation,
                                                     location => File.ReadAllText(location.FileName).Substring(location.Span.Start, location.Span.Length));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error during library compilation: " + ex.Message);
            }
        }
        private static void Execute([NotNull] ModuleDefinition moduleDefinition, [NotNull] ILogger logger, [NotNull] string addInDirectoryPath, [NotNull] string assemblyFilePath, [NotNull] IList <string> referenceCopyLocalPaths)
        {
            var entryPoint = moduleDefinition.EntryPoint;

            if (entryPoint == null)
            {
                logger.LogError("No entry point found in target module.");
                return;
            }

            TypeDefinition splashScreenControl;

            try
            {
                splashScreenControl = moduleDefinition.Types.Single(HasSplashScreenAttribute);
            }
            catch (Exception ex)
            {
                logger.LogError("No single class with the [SplashScreen] attribute found: " + ex.Message);
                return;
            }

            byte[] bitmapData;

            try
            {
                bitmapData = BitmapGenerator.Generate(addInDirectoryPath, assemblyFilePath, splashScreenControl.FullName, referenceCopyLocalPaths);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return;
            }

            var splashScreenControlBamlResourceName = splashScreenControl.Name.ToLowerInvariant() + ".baml";

            ResourceHelper.UpdateResources(moduleDefinition, SplashResourceName, bitmapData, splashScreenControlBamlResourceName);

            moduleDefinition.Types.Remove(splashScreenControl);

            var attribute = GetSplashScreenAttribute(splashScreenControl);

            var minimumVisibilityDuration = attribute.GetPropertyValue(MinimumVisibilityDurationPropertyName, 4.0);
            var fadeoutDuration           = attribute.GetPropertyValue(FadeoutDurationPropertyName, 1.0);

            var referencedModule = attribute.AttributeType.Resolve().Module;

            var adapterType = referencedModule.Types.Single(type => type.Name == SplashScreenAdapterTypeName);

            var importer = new CodeImporter(moduleDefinition);

            adapterType = importer.Import(adapterType);

            importer.ILMerge();

            var adapterTypeConstructor = adapterType.GetConstructors().Single(ctor => ctor.Parameters.Count == 3);

            entryPoint.Body.Instructions.InsertRange(0,
                                                     Instruction.Create(OpCodes.Ldstr, SplashResourceName),
                                                     Instruction.Create(OpCodes.Ldc_R8, minimumVisibilityDuration),
                                                     Instruction.Create(OpCodes.Ldc_R8, fadeoutDuration),
                                                     Instruction.Create(OpCodes.Newobj, moduleDefinition.ImportReference(adapterTypeConstructor)),
                                                     Instruction.Create(OpCodes.Pop)
                                                     );
        }
Example #19
0
        private static ICollection <ModuleDefinition> ImportRemainingTypes(ICollection <ModuleDefinition> importedModules, CodeImporter codeImporter)
        {
            var updatedModules = new HashSet <ModuleDefinition>();

            while (true)
            {
                var modulesToUpdate = importedModules.Except(updatedModules).ToList();
                if (!modulesToUpdate.Any())
                {
                    break;
                }

                foreach (var type in modulesToUpdate.SelectMany(module => module.GetTypes().Where(t => t.Name != "<Module>")))
                {
                    codeImporter.ImportType(type, null);
                }

                updatedModules  = new HashSet <ModuleDefinition>(updatedModules.Concat(modulesToUpdate));
                importedModules = codeImporter.ListImportedModules();
            }

            return(importedModules);
        }