public IEnumerable <AssemblyDefinition> GetIncludedReferences() { var includedReferences = new List <AssemblyDefinition>(); var resolver = _moduleDefinition.AssemblyResolver; foreach (var assemblyReference in _moduleDefinition.AssemblyReferences) { var referenceName = assemblyReference.Name; if (!ShouldReferenceBeIncluded(assemblyReference)) { continue; } var assembly = resolver.Resolve(referenceName); if (assembly != null) { FodyEnvironment.LogInfo(string.Format("Including reference '{0}'", referenceName)); includedReferences.Add(assembly); } } if (!_configuration.ExcludeOptimizedAssemblies) { var splittedReferences = _moduleWeaver.References.Split(new [] { ";" }, StringSplitOptions.RemoveEmptyEntries); foreach (var splittedReference in splittedReferences) { var assemblyDefinition = AssemblyDefinition.ReadAssembly(splittedReference); var isIncluded = (from reference in includedReferences where string.Equals(reference.FullName, assemblyDefinition.FullName) select reference).Any(); if (!isIncluded) { var referenceName = assemblyDefinition.Name.Name; if (!ShouldReferenceBeIncluded(assemblyDefinition.Name)) { continue; } var assembly = resolver.Resolve(referenceName); if (assembly != null) { FodyEnvironment.LogInfo(string.Format("Including reference '{0}', it was optimized away by the compiler but still adding it", referenceName)); includedReferences.Add(assembly); } } } } return(includedReferences); }
public void Execute() { if (!FodyEnvironment.IsCatelMvvmAvailable) { FodyEnvironment.LogInfo("Skipping weaving of exposed properties because this is an MVVM feature"); return; } var warningChecker = new ExposedPropertiesWarningChecker(_catelTypeNodeBuilder); warningChecker.Execute(); var weaver = new ExposedPropertiesWeaver(_catelTypeNodeBuilder, _msCoreReferenceFinder); weaver.Execute(); }
private bool ShouldReferenceBeIncluded(AssemblyNameReference assemblyNameReference) { var assemblyName = assemblyNameReference.Name; var assemblyNameLowered = assemblyNameReference.Name.ToLower(); foreach (var knownIgnoredAssembly in KnownIgnoredAssemblies) { if (assemblyNameLowered.Contains(knownIgnoredAssembly.ToLower())) { FodyEnvironment.LogInfo(string.Format("Ignoring '{0}' because it is a known assembly to be ignored", assemblyName)); return(false); } } if (_configuration.IncludeAssemblies.Any()) { bool contains = _configuration.IncludeAssemblies.Any(x => string.Equals(assemblyNameLowered, x.ToLower())); if (!contains) { FodyEnvironment.LogInfo(string.Format("Ignoring '{0}' because it is not in the included list", assemblyName)); } return(contains); } if (_configuration.ExcludeAssemblies.Any()) { var contains = _configuration.ExcludeAssemblies.Any(x => string.Equals(assemblyNameLowered, x.ToLower())); if (contains) { FodyEnvironment.LogInfo(string.Format("Ignoring '{0}' because it is in the excluded list", assemblyName)); } return(!contains); } return(true); }
public MethodDefinition Execute() { var debugWriteLineMethod = FindDebugWriteLineMethod(); if (debugWriteLineMethod == null) { FodyEnvironment.LogInfo("Can't find Debug.WriteLine, won't be writing debug info during assembly loading"); } var loadMethod = new MethodDefinition("LoadTypesOnStartup", MethodAttributes.Assembly | MethodAttributes.Static | MethodAttributes.HideBySig, _moduleDefinition.ImportReference(_msCoreReferenceFinder.GetCoreTypeReference("Void"))); var type = _msCoreReferenceFinder.GetCoreTypeReference("Type").Resolve(); var typeImported = _moduleDefinition.ImportReference(type); var getTypeFromHandleMethod = type.Methods.First(x => string.Equals(x.Name, "GetTypeFromHandle")); var getTypeFromHandle = _moduleDefinition.ImportReference(getTypeFromHandleMethod); var body = loadMethod.Body; body.SimplifyMacros(); var instructions = body.Instructions; if (instructions.Count == 0) { instructions.Add(Instruction.Create(OpCodes.Ret)); } var referenceSelector = new ReferenceSelector(_moduleWeaver, _moduleDefinition, _configuration); // Note: we are looping reversed to easily add try/catch mechanism foreach (var assembly in referenceSelector.GetIncludedReferences().Reverse()) { var firstType = assembly.MainModule.Types.FirstOrDefault(x => x.IsClass && x.IsPublic); if (firstType != null) { FodyEnvironment.LogInfo($"Adding code to force load assembly '{assembly.Name}'"); if (debugWriteLineMethod != null) { // L_0001: ldstr "Loading assembly TestAssemblyToReference" //L_0006: call void [System]System.Diagnostics.Debug::WriteLine(string) // Temporarily disabled because we first need to investigate if this is ever useful //instructions.Add(Instruction.Create(OpCodes.Ldstr, string.Format("Loading assembly {0}", assembly.Name))); //instructions.Add(Instruction.Create(OpCodes.Call, debugWriteLineMethod)); } // var type = typeof(FirstTypeInAssembly); // == //L_000a: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) var firstTypeImported = _moduleDefinition.ImportReference(firstType); var variable = new VariableDefinition(typeImported); body.Variables.Insert(0, variable); var instructionsToAdd = new[] { Instruction.Create(OpCodes.Ldtoken, firstTypeImported), Instruction.Create(OpCodes.Call, getTypeFromHandle), Instruction.Create(OpCodes.Stloc, variable) }; instructions.Insert(0, instructionsToAdd); if (_configuration.WrapInTryCatch) { var firstInstructionAfterInjectedSet = instructions[instructionsToAdd.Length]; // Pop means empty catch var emptyCatchInstructions = new[] { Instruction.Create(OpCodes.Leave_S, firstInstructionAfterInjectedSet), Instruction.Create(OpCodes.Pop), Instruction.Create(OpCodes.Leave_S, firstInstructionAfterInjectedSet) }; instructions.Insert(instructionsToAdd.Length, emptyCatchInstructions); var tryStartInstruction = instructionsToAdd.First(); var tryEndInstruction = emptyCatchInstructions.Skip(1).First(); var handlerStartInstruction = emptyCatchInstructions.Skip(1).First(); var handlerEndInstruction = firstInstructionAfterInjectedSet; var handler = new ExceptionHandler(ExceptionHandlerType.Catch) { TryStart = tryStartInstruction, TryEnd = tryEndInstruction, HandlerStart = handlerStartInstruction, HandlerEnd = handlerEndInstruction, CatchType = _moduleDefinition.ImportReference(_msCoreReferenceFinder.GetCoreTypeReference("Exception")) }; body.ExceptionHandlers.Insert(0, handler); } } } instructions.Add(Instruction.Create(OpCodes.Ret)); body.OptimizeMacros(); //.class public abstract auto ansi sealed beforefieldinit LoadAssembliesOnStartup extends [mscorlib]System.Object var typeDefinition = new TypeDefinition(string.Empty, "LoadAssembliesOnStartup", TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, _moduleDefinition.ImportReference(_msCoreReferenceFinder.GetCoreTypeReference("System.Object"))); typeDefinition.Methods.Add(loadMethod); _moduleDefinition.Types.Add(typeDefinition); return(loadMethod); }
private bool ShouldReferenceBeIncluded(AssemblyNameReference assemblyNameReference) { var assemblyName = assemblyNameReference.Name; var assemblyNameLowered = assemblyNameReference.Name.ToLower(); foreach (var knownIgnoredAssembly in KnownIgnoredPartialAssemblies) { var name = knownIgnoredAssembly.ToLower(); if (assemblyNameLowered.Contains(name)) { FodyEnvironment.LogInfo($"Ignoring '{assemblyName}' because it is a known assembly to be ignored (via partial match '{knownIgnoredAssembly}')"); return(false); } } foreach (var knownIgnoredAssembly in KnownIgnoredExactAssemblies) { var name = knownIgnoredAssembly.ToLower(); if (assemblyNameLowered.Equals(name)) { FodyEnvironment.LogInfo($"Ignoring '{name}' because it is a known assembly to be ignored (via exact match '{knownIgnoredAssembly}')"); return(false); } } if (_configuration.IncludeAssemblies.Any()) { var contains = _configuration.IncludeAssemblies.Any(x => string.Equals(assemblyNameLowered, x.ToLower())); if (!contains) { FodyEnvironment.LogInfo($"Ignoring '{assemblyName}' because it is not in the included list"); } return(contains); } if (_configuration.ExcludeAssemblies.Any()) { var contains = _configuration.ExcludeAssemblies.Any(x => string.Equals(assemblyNameLowered, x.ToLower())); if (contains) { FodyEnvironment.LogInfo($"Ignoring '{assemblyName}' because it is in the excluded list"); return(false); } // Don't return here, allow it to check for private assemblies, we don't want to include *everything* // just because 1 or 2 are being excluded } if (_configuration.ExcludeSystemAssemblies) { foreach (var systemAssemblyPrefix in SystemAssemblyPrefixes) { // Special case: System.dll, we don't want to include "System" to the prefixes, that would be too strict if (assemblyName.IndexOf(systemAssemblyPrefix, StringComparison.OrdinalIgnoreCase) == 0 || assemblyName.Equals("System", StringComparison.OrdinalIgnoreCase)) { FodyEnvironment.LogInfo($"Ignoring '{assemblyName}' because it is a system assembly"); return(false); } } } if (_configuration.ExcludePrivateAssemblies) { if (IsPrivateReference(assemblyName)) { FodyEnvironment.LogInfo($"Ignoring '{assemblyName}' because it is a private assembly"); return(false); } // TODO: How to determine private assemblies, do we have access to the csproj? //foreach (var systemAssemblyPrefix in SystemAssemblyPrefixes) //{ // if (assemblyNameLowered.IndexOf(systemAssemblyPrefix, StringComparison.OrdinalIgnoreCase) == 0) // { // FodyEnvironment.LogInfo($"Ignoring '{assemblyName}' because it is a system assembly"); // return false; // } //} } return(_configuration.OptOut); }