public void TestConversion1( ) { // takes IComponentLifetime var svc = new ResolveService { ServiceType = typeof(Lazy <IRandom>) }; _fixture.Container.Resolve <Lazy <IRandom> > ( ); var resolveConv = new ResolveServiceConverter( ); Assert.NotNull(resolveConv); var value = resolveConv.Convert( svc , null , _fixture.Container , CultureInfo.CurrentCulture ); Assert.NotNull(value); Assert.IsAssignableFrom <Lazy <IRandom> > (value); var lazy = (Lazy <IRandom>)value; _output.WriteLine($"IsValueCreated = {lazy.IsValueCreated}"); _output.WriteLine($"Value = {lazy.Value}"); }
private bool FindInterfaceMethod(MethodDefinition method, MethodObject methodNode) { // multi level inheritance is flattened here foreach (var interfaceParent in method.DeclaringType.Interfaces) { var matchingMethod = InterfaceMethodsIndexedByTypeName.Get(interfaceParent.InterfaceType.FullName) .FirstOrDefault(x => SignatureKeyService.GetMethodSignature(x).Equals(SignatureKeyService.GetMethodSignature(method))); if (matchingMethod != null) { methodNode.InterfaceMethod = matchingMethod; methodNode.ImplementsType = ImplementsType.Interface; return(true); } else // might be an interface with generics. We have indexed the generic form but now search using a generic instance (instead of T, a real type) { TypeDefinition interfaceDefinition = null; var resolved = ResolveService.TryResolve(interfaceParent.InterfaceType, out interfaceDefinition); if (resolved && interfaceDefinition.GenericParameters.Any()) { return(ResolveGenericsInterface(method, methodNode, interfaceParent.InterfaceType, interfaceDefinition)); } } } return(false); }
private bool IsValidateInstruction(Instruction instruction) { if (instruction.OpCode.OperandType == OperandType.InlineMethod) { var methodRef = (MethodReference)instruction.Operand; MethodDefinition methodDef = null; var resolved = ResolveService.TryResolve(methodRef, out methodDef); return(resolved); } return(true); }
private static MethodDefinition ResolveMethod(Instruction instruction) { MethodDefinition instructionMethodDef = null; var subMethodResolved = ResolveService.TryResolve((MethodReference)instruction.Operand, out instructionMethodDef); if (!subMethodResolved) { throw new ILParseException("Could not resolve " + ((MethodReference)instruction.Operand).FullName); } return(instructionMethodDef); }
private void EmptyIndexes() { _assembliesProcessed = new HashSet <string>(); _modulesToAnalyze = new List <ModuleDefinition>(); _assignmentGraphIndexer.CleanIndexes(); _delegateIndexer.CleanIndexes(); _methodIndexer.CleanIndexes(); _typeService.CleanIndexes(); ResolveService.CleanIndexes(); PropertyService.CleanIndexes(); SignatureKeyService.CleanIndexes(); }
private void ValidateInstruction(Instruction instruction) { if (instruction.OpCode.OperandType == OperandType.InlineMethod) { var methodRef = (MethodReference)instruction.Operand; MethodDefinition methodDef = null; var resolved = ResolveService.TryResolve(methodRef, out methodDef); if (!resolved) { throw new ILParseException("Could not resolve " + methodRef.FullName); } } }
public static TypeCategory GetTypeCategory(Instruction instruction) { if (instruction.OpCode.OperandType == OperandType.InlineMethod) { MethodDefinition method = null; var resolved = ResolveService.TryResolve((MethodReference)instruction.Operand, out method); if (method.DeclaringType.IsInterface) { return(TypeCategory.Interface); } } return(TypeCategory.Concrete); }
private bool UsesEntityFramework(MethodObject currentMethod) { bool usesEfField = false; bool usesEfMethod = false; bool classInheritsFromObjectContext = false; if (currentMethod.HasImplementation()) { usesEfField = currentMethod.FieldsRead.Any( t => t.DeclaringType.Namespace.Equals("System.Data.EntityClient") || t.DeclaringType.Namespace.Equals("System.Data.Objects")); if (!usesEfField) { var declaringTypes = currentMethod.MethodsCalled .Select(t => t.MethodCalled.DeclaringType) .GroupBy(x => x.FullName) .Select(x => x.First()) .ToList(); foreach (var declaringType in declaringTypes) { if (declaringType.Namespace.Equals("System.Data.EntityClient") || declaringType.Namespace.Equals("System.Data.Objects") || declaringType.Namespace.Equals("System.Data.Entity")) { usesEfMethod = true; break; } TypeDefinition typeDef = null; if (ResolveService.TryResolve(declaringType, out typeDef)) { if (typeDef.BaseType != null && (typeDef.BaseType.Namespace.Equals("System.Data.EntityClient") || typeDef.BaseType.Namespace.Equals("System.Data.Objects") || typeDef.BaseType.Namespace.Equals("System.Data.Entity"))) { usesEfMethod = true; break; } } } } } return(usesEfField || usesEfMethod || classInheritsFromObjectContext); }
private void IndexDelegateInvocation(Instruction instruction, MethodReference invokedDelegate, MethodDefinition parentMethod) { //var instructionKey = InstructionKeyService.GetInstructionKey(instruction, parentMethod); var targetKey = invokedDelegate.DeclaringType.GetKey() + "::.ctor(System.Object,System.IntPtr)>>1"; var assignmentTrees = _assignmentGraphWalker.PerformBacktrackingSearch(instruction, parentMethod, new DefaultSourceDetector(new HashSet <string>() { targetKey }), new List <GoToInstancePattern>() { new GoToInstancePattern() { TypeMustHavePattern = invokedDelegate.DeclaringType.FullName, MemberMustHavePattern = "Invoke", TryInstance = TryInstance.Only } }, new List <string>()); foreach (var result in assignmentTrees) { foreach (var node in result.FoundNodes) { if (node.Triple.From.Instruction.OpCode.Name == "ldvirtftn") { var methodRef = (MethodReference)node.Triple.From.Instruction.Operand; MethodDefinition assignedMethod = null; var resolved = ResolveService.TryResolve(methodRef, out assignedMethod); if (resolved) { var indexedDelegate = new IndexedDelegate(); indexedDelegate.AssignedMethod = assignedMethod; indexedDelegate.MethodAssignmentInstruction = node.Triple.From.Instruction; string key = GetDelegateKey(parentMethod, invokedDelegate); _delegateMethods.Add(key, indexedDelegate); } } } } }
public static bool IsDelegateInvocation(MethodReference calledMethod) { if (calledMethod.FullName.IndexOf("__") > -1) // is a compiler generated class { return(false); } TypeDefinition declaringType = null; var resolved = ResolveService.TryResolveMethodDeclaringType(calledMethod, out declaringType); if (resolved) { return(declaringType != null && declaringType.BaseType != null && declaringType.BaseType.FullName.Equals("System.MulticastDelegate") && calledMethod.Name.Equals("Invoke")); } return(false); }
public void TestSetup() { this.resolveService = new ResolveService(); this.dataModelUtils = new DataModelUtils(); this.requestUtils = new RequestUtils(); this.resolveService.DataModelUtils = this.dataModelUtils; this.engineeringModelIid = Guid.NewGuid(); this.siteDirectoryInfo = new DtoInfo(typeof(SiteDirectory).Name, Guid.NewGuid()); this.simpleQuantityKindInfo = new DtoInfo(typeof(SimpleQuantityKind).Name, Guid.NewGuid()); this.engineeringModelInfo = new DtoInfo(typeof(EngineeringModel).Name, Guid.NewGuid()); this.bookInfo = new DtoInfo(typeof(Book).Name, Guid.NewGuid()); this.optionInfo = new DtoInfo(typeof(Option).Name, Guid.NewGuid()); this.parameterInfo = new DtoInfo(typeof(Parameter).Name, Guid.NewGuid()); this.aliasInfo = new DtoInfo(typeof(Alias).Name, Guid.NewGuid()); }
private Tuple <bool, TypeDefinition> IsAsync(MethodDefinition method) { if (method.HasBody) { var firstInstr = method.Body.Instructions.First(); if (firstInstr.OpCode.Code == Mono.Cecil.Cil.Code.Newobj && firstInstr.Operand != null) { var methodRef = (MethodReference)firstInstr.Operand; MethodDefinition methodDefinition = null; var resolved = ResolveService.TryResolve(methodRef, out methodDefinition); if (resolved) { if (methodDefinition.DeclaringType.Interfaces.Any(x => x.InterfaceType.FullName.Equals("System.Runtime.CompilerServices.IAsyncStateMachine"))) { return(Tuple.Create(true, methodDefinition.DeclaringType)); } } } } return(Tuple.Create <bool, TypeDefinition>(false, null)); }
public static bool IsStaticMember(Instruction instruction) { if (instruction.OpCode.OperandType == OperandType.InlineMethod) { MethodDefinition methodDef = null; var resolved = ResolveService.TryResolve((MethodReference)instruction.Operand, out methodDef); if (resolved) { return(methodDef.IsStatic); } } else if (instruction.OpCode.OperandType == OperandType.InlineField) { FieldDefinition fieldDef = null; var resolved = ResolveService.TryResolve((FieldReference)instruction.Operand, out fieldDef); if (resolved) { return(fieldDef.IsStatic); } } return(false); }
public static string GetConcreteInheritance(Instruction instruction) { TypeReference typeRef = null; var memberRef = instruction.Operand as MemberReference; if (memberRef != null) { if (TypeService.ShouldSkipResolve(memberRef.DeclaringType)) { return(null); } TypeDefinition typeDef = null; bool resolved = ResolveService.TryResolve(memberRef.DeclaringType, out typeDef); if (resolved) { if (typeDef.BaseType != null) { return(typeDef.BaseType.FullName); } } } else if (instruction.OpCode.OperandType == OperandType.InlineArg) { var field = (ParameterReference)instruction.Operand; TypeDefinition typeDef = null; bool resolved = ResolveService.TryResolve(field.ParameterType, out typeDef); if (resolved) { return(typeDef.BaseType.FullName); } } return(null); }
public static string GetFromInstanceOwnerKey(Instruction instruction, ObjectType objectType, MethodDefinition parentMethod) { if (objectType == ObjectType.NotDefined || objectType == ObjectType.ReturnValue || objectType == ObjectType.InlineString || objectType == ObjectType.None || objectType == ObjectType.LocalVariable || objectType == ObjectType.InlineNumber) { return(null); } // for argument we use the key of the method if (objectType == ObjectType.Argument) { return(parentMethod.GetKey()); } Instruction priorInstruction = null; if (objectType == ObjectType.Method) { MethodDefinition methodDef = null; var resolved = ResolveService.TryResolve((MethodReference)instruction.Operand, out methodDef); if (!resolved) { return(null); } else if (methodDef.IsStatic || methodDef.Name.Equals(".ctor")) { return(parentMethod.GetKey()); } else if (methodDef.GetOwnerKey().Equals(parentMethod.GetOwnerKey())) { return(methodDef.GetOwnerKey()); } priorInstruction = MethodArgumentInstructionParser.GetPriorInstruction(parentMethod, methodDef, instruction); } else if (objectType == ObjectType.Field) { var fieldReference = (FieldReference)instruction.Operand; if (fieldReference.DeclaringType.FullName.Equals(parentMethod.DeclaringType.FullName)) { return(null); } priorInstruction = instruction.Previous; } else { return(null); //MethodDefinition methodDef = null; //var resolved = ResolveService.TryResolve((MethodReference)instruction.Operand, out methodDef); //if (methodDef.IsStatic || methodDef.Name.Equals(".ctor")) // return parentMethod.GetKey(); //if (methodDef.GetOwnerKey().Equals(parentMethod.GetOwnerKey())) // return methodDef.GetOwnerKey(); //priorInstruction = instruction.Previous; } if (priorInstruction == null) { return(null); } var ownerObjectType = GetFromObjectType(priorInstruction); if (!IsSupportedObject(ownerObjectType)) { return(null); } var ownerInstanceKey = GetObjectKey(priorInstruction, ownerObjectType, parentMethod); return(ownerInstanceKey); }
private void FindFieldsAndMethods(MethodDefinition method, MethodObject methodNode, bool allowRecursion) { if (!method.HasBody) { return; } List <Instruction> instructions = null; var isAsync = IsAsync(method); if (isAsync.Item1) { instructions = GetInstructionsOfAsyncMethod(isAsync.Item2); } else { instructions = method.Body.Instructions.ToList(); } foreach (var instruction in instructions) { try { if (instruction.OpCode.Code == Mono.Cecil.Cil.Code.Call || instruction.OpCode.Code == Mono.Cecil.Cil.Code.Calli || instruction.OpCode.Code == Mono.Cecil.Cil.Code.Callvirt || instruction.OpCode.Code == Mono.Cecil.Cil.Code.Newobj) { var methodRef = (MethodReference)instruction.Operand; MethodDefinition methodDef = null; var resolved = ResolveService.TryResolve(methodRef, out methodDef); if (!resolved) { // log error continue; } if (DelegateIndexer.IsDelegateInvocation(methodRef)) { var concreteMethods = _delegateIndexer.GetAssignedMethods(method, methodRef); foreach (var concreteMethod in concreteMethods) { var delegateCall = new MethodCall(); delegateCall.Instruction = concreteMethod.MethodAssignmentInstruction; delegateCall.MethodCalled = concreteMethod.AssignedMethod; delegateCall.OwnerMethod = method; methodNode.MethodsCalled.Add(delegateCall); } } else if (IsLazilyEvaluated(instruction, methodDef)) { var nestedMethods = ExtractNestedMethods(methodDef.DeclaringType); foreach (var nestedMethod in nestedMethods) { if (allowRecursion) { FindFieldsAndMethods(nestedMethod, methodNode, false); } } } else if (!methodRef.FullName.Equals("System.Void System.Object::.ctor()")) { bool funcMethodCallsFound = false; // try to detect funcs if (methodRef.Parameters.Any()) { var rootNode = new InstructionTreeNode(); MethodArgumentInstructionParser.GetParameterInstructionTree(method, methodRef, instruction, rootNode); foreach (var loadFunctionNode in rootNode.GetDescendants().Where(x => x.Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Ldftn)) { // except for delegates! var funcCall = new MethodCall(); funcCall.Instruction = loadFunctionNode.Instruction; funcCall.MethodCalled = loadFunctionNode.Instruction.Operand as MethodReference; funcCall.OwnerMethod = method; methodNode.MethodsCalled.Add(funcCall); funcMethodCallsFound = true; } } bool isCompilerServicesRelated = false; if (isAsync.Item1 && (methodRef.DeclaringType.FullName.StartsWith("System.Runtime.CompilerServices") || methodRef.DeclaringType.FullName.StartsWith("System.Threading.Tasks"))) { isCompilerServicesRelated = true; } // if not a func and not an async related CompilerServices call then go ahead and register the call if (!funcMethodCallsFound && !isCompilerServicesRelated) { var methodCall = new MethodCall(); methodCall.Instruction = instruction; methodCall.MethodCalled = methodRef; methodCall.OwnerMethod = method; methodNode.MethodsCalled.Add(methodCall); } } } else if (instruction.OpCode.OperandType == OperandType.InlineField) { var field = (FieldReference)instruction.Operand; if ((instruction.OpCode.Name.StartsWith("ldfld") || instruction.OpCode.Name.StartsWith("ldsfld")) && field.Name.IndexOf("BackingField") == -1) { methodNode.FieldsRead.Add(field); } } else if (instruction.OpCode.Code == Mono.Cecil.Cil.Code.Ldftn) { var methodRef = (MethodReference)instruction.Operand; MethodDefinition functionDefinition = null; var resolved = ResolveService.TryResolve(methodRef, out functionDefinition); if (!resolved) { // log error continue; } if (allowRecursion) { FindFieldsAndMethods(functionDefinition, methodNode, false); } } } catch (Exception ex) { // log it } } }
private static Instruction GetParameterInstructionTreeForNormalMethod(MethodReference parentMethodRef, MethodReference method, Instruction instruction, InstructionTreeNode parentNode) { MethodDefinition parentMethod = parentMethodRef.Resolve(); Instruction targetMethodInstruction = instruction; MethodDefinition targetMethodDef = null; var resolved = ResolveService.TryResolve((MethodReference)instruction.Operand, out targetMethodDef); if (!resolved) { throw new ILParseException("Could not resolve " + ((MethodReference)instruction.Operand).FullName); } var parameterCount = method.Parameters.Count; if (parentNode.Instruction == null) { parentNode.Instruction = instruction; } for (int i = 0; i < parameterCount; i++) { if (instruction.Previous == null) { throw new ILParseException("Unexpectedly reached the end of the instructions while analysing " + parentMethodRef.FullName); } instruction = GetPreviousInstruction(instruction); if (ShouldSkip(instruction)) { instruction = GetPreviousInstruction(instruction); } var childNode = new InstructionTreeNode(); childNode.Instruction = instruction; parentNode.ChildInstructions.Add(childNode); if (instruction.OpCode.OperandType == OperandType.InlineMethod) { var instructionMethodDef = ResolveMethod(instruction); if (instructionMethodDef.Parameters.Any()) { var lastInstructionOfParameters = GetParameterInstructionTree(parentMethodRef, instructionMethodDef, instruction, childNode); instruction = lastInstructionOfParameters; //if (AreInstructionsChained(instruction, lastInstructionOfParameters.Previous)) // instruction = lastInstructionOfParameters.Previous; // move to chained instruction so later call jumps chained instructions } } instruction = JumpPastAnyOwnerInstructions(instruction, parentMethod); } instruction = JumpAnyJumpableInstructionsOfTargetMethod(targetMethodInstruction, instruction, targetMethodDef, parentMethod); //if(TargetMethodHasJumpablePreviousInstruction(targetMethodInstruction, instruction, targetMethodDef, parentMethod)) // instruction = GetPreviousInstruction(instruction); //if (HasThis(callingMethod, methodDef) && instruction.OpCode.Code != Mono.Cecil.Cil.Code.Ldarg_0) // instruction = GetPreviousInstruction(instruction); return(instruction); }