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"); }
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));
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); }
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); }
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 !));
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); }
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)); }
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); }
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); }
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); } }
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); }
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); }
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); }
/// <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) ); }
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); }