public ReturnNode(MethodGraph graph) : base(graph) { AddInputExecPin("Exec"); SetupSecondaryNodeEvents(); }
private void CrossAssemblyWalk(MethodGraph methodGraph, MethodNode rootMethod, MethodObject currentMethod, int depth, ExploreTreeNode callTreeNode) { if (IsRecursiveLoop(callTreeNode)) { return; } if (!currentMethod.HasImplementation()) { // Perhaps log it somewhere in debug mode //File.AppendAllText("No_Implementation.txt", currentMethod.GetMethodDefinition().FullName); return; } var isCrossAssemblyCall = IsCrossAssemblyCall(rootMethod, currentMethod, depth); if (isCrossAssemblyCall) { // if it is a simple property access then we don't care. Only add it if the access is interesting if (IsNoteworthyMethodCall(currentMethod)) { var publicMethod = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, currentMethod); rootMethod.CrossAssemblyCalls.Add(publicMethod); } } else { // continue down the call tree unless the called method is of another assembly // the call tree originating at that method will be generated when that assembly is analyzed ContinueDownCrossAssemblyTree(methodGraph, rootMethod, currentMethod, depth, callTreeNode); } }
public void CreateMainMethod() { mainMethod = new MethodGraph("Main") { Class = cls, Modifiers = MethodModifiers.Static }; MethodSpecifier stringLengthSpecifier = new MethodSpecifier("StringLength", new MethodParameter[0], new List <TypeSpecifier>() { TypeSpecifier.FromType <int>() }, MethodModifiers.None, MemberVisibility.Public, TypeSpecifier.FromType <string>(), Array.Empty <BaseType>()); //MethodSpecifier writeConsoleSpecifier = typeof(Console).GetMethods().Single(m => m.Name == "WriteLine" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(string)); TypeSpecifier stringType = TypeSpecifier.FromType <string>(); MethodSpecifier writeConsoleSpecifier = new MethodSpecifier("WriteLine", new MethodParameter[] { new MethodParameter("argName", stringType, MethodParameterPassType.Default, false, null) }, new BaseType[0], MethodModifiers.None, MemberVisibility.Public, TypeSpecifier.FromType(typeof(Console)), new BaseType[0]); // Create nodes LiteralNode stringLiteralNode = LiteralNode.WithValue(mainMethod, "Hello World"); VariableSetterNode setStringNode = new VariableSetterNode(mainMethod, new VariableSpecifier("testVariable", TypeSpecifier.FromType <string>(), MemberVisibility.Public, MemberVisibility.Public, cls.Type, VariableModifiers.None)); CallMethodNode getStringLengthNode = new CallMethodNode(mainMethod, stringLengthSpecifier); CallMethodNode writeConsoleNode = new CallMethodNode(mainMethod, writeConsoleSpecifier); // Connect node execs GraphUtil.ConnectExecPins(mainMethod.EntryNode.InitialExecutionPin, setStringNode.InputExecPins[0]); GraphUtil.ConnectExecPins(setStringNode.OutputExecPins[0], getStringLengthNode.InputExecPins[0]); GraphUtil.ConnectExecPins(getStringLengthNode.OutputExecPins[0], writeConsoleNode.InputExecPins[0]); GraphUtil.ConnectExecPins(writeConsoleNode.OutputExecPins[0], mainMethod.ReturnNodes.First().InputExecPins[0]); // Connect node data GraphUtil.ConnectDataPins(stringLiteralNode.ValuePin, setStringNode.NewValuePin); GraphUtil.ConnectDataPins(getStringLengthNode.OutputDataPins[0], writeConsoleNode.ArgumentPins[0]); }
public void CreateStringLengthMethod() { // Create method stringLengthMethod = new MethodGraph("StringLength") { Class = cls, Modifiers = MethodModifiers.None }; List <TypeNode> returnTypeNodes = new List <TypeNode>() { new TypeNode(stringLengthMethod, TypeSpecifier.FromType <int>()), }; for (int i = 0; i < returnTypeNodes.Count; i++) { stringLengthMethod.MainReturnNode.AddReturnType(); GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], stringLengthMethod.MainReturnNode.InputTypePins[i]); } TypeSpecifier stringType = TypeSpecifier.FromType <string>(); TypeSpecifier intType = TypeSpecifier.FromType <int>(); // Create nodes VariableGetterNode getStringNode = new VariableGetterNode(stringLengthMethod, new VariableSpecifier("testVariable", stringType, MemberVisibility.Public, MemberVisibility.Public, stringType, VariableModifiers.None)); VariableGetterNode getLengthNode = new VariableGetterNode(stringLengthMethod, new VariableSpecifier("Length", intType, MemberVisibility.Public, MemberVisibility.Public, stringType, VariableModifiers.None)); // Connect node execs GraphUtil.ConnectExecPins(stringLengthMethod.EntryNode.InitialExecutionPin, stringLengthMethod.ReturnNodes.First().ReturnPin); // Connect node data GraphUtil.ConnectDataPins(getStringNode.ValuePin, getLengthNode.TargetPin); GraphUtil.ConnectDataPins(getLengthNode.ValuePin, stringLengthMethod.ReturnNodes.First().InputDataPins[0]); }
private static void CreateObjectMethodGraphs(GenesisContext genesis, TypeInfo cls, ObjectGraph obj) { var events = new List <string>(); foreach (var m in cls.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (m.Name.StartsWith("get_") || m.Name.StartsWith("set_")) { continue; //already did property accessors } if (m.Name.StartsWith("add_") || m.Name.StartsWith("remove_")) { var name = m.Name.Split('_')[1]; //just get the event Name if (!events.Contains(name)) { events.Add(name); } } Debug.WriteLine($@"Method:{(_nullableRegex.IsMatch(m.Name) ? _nullableRegex.Match(m.Name).Value : m.Name)}"); var methodGraph = new MethodGraph { Name = _nullableRegex.IsMatch(m.Name) ? _nullableRegex.Match(m.Name).Value : m.Name, MethodVisibility = MethodVisibilities.Public, ReturnDataType = m.ReturnType, ReturnTypeFormattedName = m.ReturnType.GetFormattedName(), HasGenericParams = m.ContainsGenericParameters, IsGeneric = m.IsGenericMethod, FormattedGenericArguments = m.GetGenericArguments().ToFormattedNames(), }; foreach (var par in m.GetParameters().OrderBy(o => o.Position)) { var mp = new ParameterGraph { DataType = par.ParameterType, DataTypeFormattedName = par.ParameterType.GetFormattedName(), DisplayName = par.ParameterType.GetDisplayName(), Name = par.Name, IsOut = par.IsOut, IsIn = par.IsIn, IsOptional = par.IsOptional, Position = par.Position, IsGeneric = par.ParameterType.IsGenericType, IsGenericMethodParameter = par.ParameterType.IsGenericMethodParameter, GenericArgumentFormattedTypeNames = par.ParameterType.GetGenericArguments().ToFormattedNames(), }; methodGraph.Parameters.Add(mp); } obj.Methods.Add(methodGraph); Text.GrayLine( $"\tMethod: {m.Name}, Return: {methodGraph.ReturnTypeFormattedName}, Visibility: {(m.IsPublic ? "public" : m.IsPrivate ? "private" : "protected")}"); } genesis.Objects.Add(obj); }
public void TestGenerics() { // Create the open class<T> which contains a List<T> GenericType genericClassArg = new GenericType("T"); ClassGraph openClass = new ClassGraph(); openClass.Name = "OpenClass"; openClass.Namespace = "Namespace"; openClass.DeclaredGenericArguments.Add(genericClassArg); TypeSpecifier listType = TypeSpecifier.FromType(typeof(List <>)); Assert.AreEqual(listType.GenericArguments.Count, 1); listType.GenericArguments[0] = genericClassArg; MethodGraph openMethod = new MethodGraph("OpenMethod"); // Add open list parameter TypeNode listTypeNode = new TypeNode(openMethod, listType); openMethod.MainReturnNode.AddReturnType(); GraphUtil.ConnectTypePins(listTypeNode.OutputTypePins[0], openMethod.MainReturnNode.InputTypePins[0]); GraphUtil.ConnectExecPins(openMethod.EntryNode.InitialExecutionPin, openMethod.ReturnNodes.First().ReturnPin); openClass.Methods.Add(openMethod); // Create the closed class which contains a List<string> ClassGraph closedClass = new ClassGraph(); closedClass.Name = "ClosedClass"; closedClass.Namespace = "Namespace"; TypeSpecifier closedListType = TypeSpecifier.FromType <string>(); MethodGraph closedMethod = new MethodGraph("ClosedMethod"); // Add closed list parameter TypeNode closedListTypeNode = new TypeNode(closedMethod, closedListType); closedMethod.MainReturnNode.AddReturnType(); GraphUtil.ConnectTypePins(closedListTypeNode.OutputTypePins[0], closedMethod.MainReturnNode.InputTypePins[0]); GraphUtil.ConnectExecPins(closedMethod.EntryNode.InitialExecutionPin, closedMethod.ReturnNodes.First().ReturnPin); closedClass.Methods.Add(closedMethod); // Translate the classes ClassTranslator translator = new ClassTranslator(); string openClassTranslated = translator.TranslateClass(openClass); string closedClassTranslated = translator.TranslateClass(closedClass); }
private void DoCrossAssemblyWalk(MethodGraph methodGraph, string companyAssembliesPattern, ModuleDefinition module, string moduleMessagee) { var publicMethods = DecompilerService.GetPublicMethods(companyAssembliesPattern, module) .Where(x => !IsBlackListed(x)) .OrderBy(x => x.DeclaringType.Name) .ThenBy(x => x.Name) .ToList(); int methodCount = publicMethods.Count; var publicMethodsAnalyzed = new HashSet <string>(); _methodNodeLookup.Clear(); int methodCounter = 0; foreach (var publicMethod in publicMethods) { methodCounter++; _logOutput.LogAnalysis("Method " + methodCounter + " of " + methodCount + " : " + moduleMessagee + " -> " + publicMethod.Name); if ((publicMethod.IsGetter || publicMethod.IsSetter) && !IsNoteworthyProperty(publicMethod)) { continue; } var signature = SignatureKeyService.GetFullMethodSignature(publicMethod); if (_methodIndexer.HasMethod(signature)) { var unfilteredRootNodes = _methodIndexer.GetMethods(signature); var rootNodes = unfilteredRootNodes.Where(x => x.HasImplementation() && ( // if it is a public implementation of a different assembly, then'll we'll filter it out here (and analyze it that assembly) (x.ConcreteMethod.IsPublic && x.ConcreteMethod.Module.Name.Equals(module.Name)) // if it is a private implementation then analyze it now as we'll miss it when we analyze the public methods of the other assembly || !x.ConcreteMethod.DeclaringType.IsPublic ) ) .ToList(); foreach (var rootMethod in rootNodes) { if (!AlreadyProcessed(rootMethod.GetMethodDefinition())) { var publicMethodNode = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, rootMethod); var callTreeNode = new ExploreTreeNode() { FullSignature = signature }; CrossAssemblyWalk(methodGraph, publicMethodNode, rootMethod, 1, callTreeNode); CacheNode(rootMethod.GetMethodDefinition(), publicMethodNode); methodGraph.AddMethodNode(publicMethodNode); } } } } }
public string GenerateLocalCsvFiles(MethodGraph methodGraph, string rootCsvFolder) { var csvFolder = PrepareCsvFolder(rootCsvFolder, methodGraph.ApplicationName, methodGraph.GraphType); GenerateMethodNodesCsv(methodGraph.GetMethodNodes(), csvFolder, methodGraph.ApplicationName); GenerateResourceAccessesCsv(methodGraph.GetResourceAccessNodes(), csvFolder, methodGraph.ApplicationName); GenerateMethodToMethodRelationshipsCsv(methodGraph.GenerateMethodRelationships(), csvFolder, methodGraph.ApplicationName); GenerateMethodToResourceRelationshipsCsv(methodGraph.GenerateResourceRelationships(), csvFolder, methodGraph.ApplicationName); return(csvFolder); }
private void ContinueDownFullTree(MethodGraph methodGraph, MethodNode parentMethodNode, MethodObject parentMethod, int depth, ExploreTreeNode callTreeNode) { foreach (var calledMethod in parentMethod.MethodsCalled) { CheckForResourceCall(methodGraph, calledMethod, parentMethod, parentMethodNode); var calledMethodSignature = SignatureKeyService.GetFullMethodSignature(calledMethod.MethodCalled); var treeNode = new ExploreTreeNode() { FullSignature = calledMethodSignature }; callTreeNode.AddChild(treeNode); bool isGenericAndIndexed = false; string genericSignature = null; var methodIsIndexed = _methodIndexer.HasMethod(calledMethodSignature); if (!methodIsIndexed) { genericSignature = SignatureKeyService.GetGenericMethodSignature(calledMethod.MethodCalled); if (!string.IsNullOrEmpty(genericSignature)) { isGenericAndIndexed = _methodIndexer.HasMethod(genericSignature); } } if (methodIsIndexed || isGenericAndIndexed) { List <MethodObject> matchingMethodNodes = null; if (methodIsIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(calledMethodSignature); } else if (isGenericAndIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(genericSignature); } foreach (var calledMethodNode in matchingMethodNodes) { var cachedRootNode = GetCachedRootNode(calledMethodNode.GetMethodDefinition()); if (cachedRootNode != null) // this is a call to an already analyzed method, we copy over the calls and resource accesses already calculated for this node { cachedRootNode.CopyCallsToNode(parentMethodNode); } else // this is not a call to a previously analyzed method, so we continue down the call tree { PublicInnerAssemblyWalk(methodGraph, parentMethodNode, calledMethodNode, depth + 1, treeNode); } } } } }
public void CreateStringLengthMethod() { List <TypeSpecifier> argumentTypes = new List <TypeSpecifier>() { TypeSpecifier.FromType <string>(), }; // Create method stringLengthMethod = new MethodGraph("StringLength") { Visibility = MemberVisibility.Public }; // Add arguments List <TypeNode> argTypeNodes = new List <TypeNode>() { new TypeNode(stringLengthMethod, TypeSpecifier.FromType <string>()), }; for (int i = 0; i < argTypeNodes.Count; i++) { ((MethodEntryNode)stringLengthMethod.EntryNode).AddArgument(); GraphUtil.ConnectTypePins(argTypeNodes[i].OutputTypePins[0], stringLengthMethod.EntryNode.InputTypePins[i]); } // Add return types List <TypeNode> returnTypeNodes = new List <TypeNode>() { new TypeNode(stringLengthMethod, TypeSpecifier.FromType <int>()), }; for (int i = 0; i < returnTypeNodes.Count; i++) { stringLengthMethod.MainReturnNode.AddReturnType(); GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], stringLengthMethod.MainReturnNode.InputTypePins[i]); } // Create nodes var getLengthNode = new VariableGetterNode(stringLengthMethod, new VariableSpecifier("Length", TypeSpecifier.FromType <int>(), MemberVisibility.Public, MemberVisibility.Public, TypeSpecifier.FromType <string>(), VariableModifiers.None)); // Connect node execs GraphUtil.ConnectExecPins(stringLengthMethod.EntryNode.InitialExecutionPin, stringLengthMethod.ReturnNodes.First().ReturnPin); // Connect node data GraphUtil.ConnectDataPins(stringLengthMethod.EntryNode.OutputDataPins[0], getLengthNode.InputDataPins[0]); GraphUtil.ConnectDataPins(getLengthNode.OutputDataPins[0], stringLengthMethod.ReturnNodes.First().InputDataPins[0]); }
private void DoDirectCallWalk(MethodGraph methodGraph, string companyAssembliesPattern, ModuleDefinition module, string moduleMessagee) { var methods = _methodIndexer.GetAllMethods(); foreach (var method in methods) { var methodNode = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, method); foreach (var calledMethod in method.MethodsCalled) { CheckForResourceCall(methodGraph, calledMethod, method, methodNode); var calledMethodSignature = SignatureKeyService.GetFullMethodSignature(calledMethod.MethodCalled); bool isGenericAndIndexed = false; string genericSignature = null; var methodIsIndexed = _methodIndexer.HasMethod(calledMethodSignature); if (!methodIsIndexed) { genericSignature = SignatureKeyService.GetGenericMethodSignature(calledMethod.MethodCalled); if (!string.IsNullOrEmpty(genericSignature)) { isGenericAndIndexed = _methodIndexer.HasMethod(genericSignature); } } if (methodIsIndexed || isGenericAndIndexed) { List <MethodObject> matchingMethodNodes = null; if (methodIsIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(calledMethodSignature); } else if (isGenericAndIndexed) { matchingMethodNodes = _methodIndexer.GetMethods(genericSignature); } foreach (var calledMethodNode in matchingMethodNodes) { AddDirectCalls(methodGraph, methodNode, calledMethodNode); } } } methodGraph.AddMethodNode(methodNode); } }
public void CreateIfElseMethod() { // Create method ifElseMethod = new MethodGraph("IfElse") { Visibility = MemberVisibility.Public }; // Add arguments List <TypeNode> argTypeNodes = new List <TypeNode>() { new TypeNode(ifElseMethod, TypeSpecifier.FromType <int>()), new TypeNode(ifElseMethod, TypeSpecifier.FromType <bool>()), }; for (int i = 0; i < argTypeNodes.Count; i++) { ((MethodEntryNode)ifElseMethod.EntryNode).AddArgument(); GraphUtil.ConnectTypePins(argTypeNodes[i].OutputTypePins[0], ifElseMethod.EntryNode.InputTypePins[i]); } // Add return types List <TypeNode> returnTypeNodes = new List <TypeNode>() { new TypeNode(ifElseMethod, TypeSpecifier.FromType <int>()), }; for (int i = 0; i < returnTypeNodes.Count; i++) { ifElseMethod.MainReturnNode.AddReturnType(); GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], ifElseMethod.MainReturnNode.InputTypePins[i]); } // Create nodes IfElseNode ifElseNode = new IfElseNode(ifElseMethod); LiteralNode literalNode = LiteralNode.WithValue(ifElseMethod, 123); // Connect exec nodes GraphUtil.ConnectExecPins(ifElseMethod.EntryNode.InitialExecutionPin, ifElseNode.ExecutionPin); GraphUtil.ConnectExecPins(ifElseNode.TruePin, ifElseMethod.ReturnNodes.First().ReturnPin); GraphUtil.ConnectExecPins(ifElseNode.FalsePin, ifElseMethod.ReturnNodes.First().ReturnPin); // Connect node data GraphUtil.ConnectDataPins(ifElseMethod.EntryNode.OutputDataPins[1], ifElseNode.ConditionPin); GraphUtil.ConnectDataPins(ifElseMethod.EntryNode.OutputDataPins[0], ifElseMethod.ReturnNodes.First().InputDataPins[0]); GraphUtil.ConnectDataPins(literalNode.ValuePin, ifElseMethod.ReturnNodes.First().InputDataPins[0]); }
public MethodGraph BuildFullGraph(string applicationName, string companyAssembliesPattern, List <ModuleDefinition> modules) { _companyAssembliesPattern = companyAssembliesPattern; var methodGraph = new MethodGraph(applicationName, GraphType.Full); int moduleCounter = 1; foreach (var module in modules) { string moduleMessagee = "Full Graph - Module " + moduleCounter + " of " + modules.Count + " " + module.Name; DoDirectCallWalk(methodGraph, companyAssembliesPattern, module, moduleMessagee); moduleCounter++; } return(methodGraph); }
public void TestTypeGraph() { MethodGraph method = new MethodGraph("Method"); var unboundListType = new TypeSpecifier("System.Collections.Generic.List", genericArguments: new BaseType[] { new GenericType("T") }); var literalNode = new LiteralNode(method, unboundListType); Assert.AreEqual(literalNode.InputTypePins.Count, 1); var typeNode = new TypeNode(method, TypeSpecifier.FromType <int>()); Assert.AreEqual(literalNode.InputTypePins.Count, 1); GraphUtil.ConnectTypePins(typeNode.OutputTypePins[0], literalNode.InputTypePins[0]); Assert.AreEqual(literalNode.InputTypePins[0].InferredType.Value, new TypeSpecifier("System.Int32")); Assert.AreEqual(literalNode.OutputDataPins[0].PinType.Value, new TypeSpecifier("System.Collections.Generic.List", genericArguments: new BaseType[] { new TypeSpecifier("System.Int32") })); }
public void CreateForLoopMethod() { // Create method forLoopMethod = new MethodGraph("ForLoop") { Visibility = MemberVisibility.Public }; // Create nodes LiteralNode maxIndexLiteralNode = LiteralNode.WithValue(forLoopMethod, 10); ForLoopNode forLoopNode = new ForLoopNode(forLoopMethod); // Connect exec nodes GraphUtil.ConnectExecPins(forLoopMethod.EntryNode.InitialExecutionPin, forLoopNode.ExecutionPin); GraphUtil.ConnectExecPins(forLoopNode.CompletedPin, forLoopMethod.ReturnNodes.First().ReturnPin); // Connect node data GraphUtil.ConnectDataPins(maxIndexLiteralNode.ValuePin, forLoopNode.MaxIndexPin); }
private void CheckForResourceCall(MethodGraph methodGraph, MethodCall calledMethod, MethodObject currentMethod, MethodNode rootMethod) { var dbMatch = _databaseResolver.IsTargetMethodMatch(calledMethod, currentMethod); if (dbMatch.IsMatch) { var databaseKey = _databaseResolver.GetDatabaseKey(dbMatch, calledMethod, currentMethod); if (databaseKey != null) { var resourceAccessNode = new ResourceAccessNode(methodGraph.GraphType, methodGraph.ApplicationName); resourceAccessNode.ConfigurationResource = ConfigurationResource.Database; resourceAccessNode.ResourceKey = databaseKey; rootMethod.AddResourceAccess(resourceAccessNode); methodGraph.AddResourceAccessNode(resourceAccessNode); } return; } }
public void TestDelegate() { // Create method MethodGraph delegateMethod = new MethodGraph("DelegateMethod") { Visibility = MemberVisibility.Public }; List <TypeNode> returnTypeNodes = new List <TypeNode>() { new TypeNode(delegateMethod, TypeSpecifier.FromType <Func <int, string, float> >()), }; for (int i = 0; i < returnTypeNodes.Count; i++) { delegateMethod.MainReturnNode.AddReturnType(); GraphUtil.ConnectTypePins(returnTypeNodes[i].OutputTypePins[0], delegateMethod.MainReturnNode.InputTypePins[i]); } MethodSpecifier delegateMethodSpecifier = new MethodSpecifier("TestMethod", new MethodParameter[] { new MethodParameter("arg1", TypeSpecifier.FromType <int>(), MethodParameterPassType.Default), new MethodParameter("arg2", TypeSpecifier.FromType <string>(), MethodParameterPassType.Default) }, new BaseType[] { TypeSpecifier.FromType <float>() }, MethodModifiers.Static, MemberVisibility.Public, TypeSpecifier.FromType <double>(), Array.Empty <BaseType>()); // Create nodes MakeDelegateNode makeDelegateNode = new MakeDelegateNode(delegateMethod, delegateMethodSpecifier); // Connect node execs GraphUtil.ConnectExecPins(delegateMethod.EntryNode.InitialExecutionPin, delegateMethod.ReturnNodes.First().ReturnPin); // Connect node data GraphUtil.ConnectDataPins(makeDelegateNode.OutputDataPins[0], delegateMethod.ReturnNodes.First().InputDataPins[0]); string translated = methodTranslator.Translate(delegateMethod, true); }
private void AddDirectCalls(MethodGraph methodGraph, MethodNode rootMethod, MethodObject currentMethod) { var isCrossAssemblyCall = IsCrossAssemblyCall(rootMethod, currentMethod, 2); var isPublicInnerAssemblyCall = IsPublicInnerAssemblyCall(rootMethod, currentMethod, 2); var currentMethodNode = GetMethodNode(methodGraph.GraphType, methodGraph.ApplicationName, currentMethod); if (IsNoteworthyMethodCall(currentMethod)) { if (isCrossAssemblyCall) { rootMethod.CrossAssemblyCalls.Add(currentMethodNode); } else if (isPublicInnerAssemblyCall) { rootMethod.PublicInnerAssemblyCalls.Add(currentMethodNode); } else { rootMethod.NonPublicInnerAssemblyCalls.Add(currentMethodNode); } } }
public DelayNode(MethodGraph graph) : base(graph) { }
public MethodEntryNode(MethodGraph graph) : base(graph) { AddOutputExecPin("Exec"); }
internal void ProcessReplacements() { foreach (var t in rewriteAssembly.GetTypes()) { bool forceImplRewrite = t.Name.StartsWith("<PrivateImplementationDetails>"); var repl = t.GetCustomAttribute <RewriteAttribute>(false); TypeGraph typeTarget = null; TypeRewrite typeRewrite = null; if (repl != null) { if (repl.action == RewriteAction.Add) { typeTarget = new TypeGraph(t, null, _graph._modules.First()); if (repl.typeName != null) { typeTarget.FullName = repl.typeName; } continue; } typeTarget = (from x in Graph.Modules from y in x.TypeGraphs where y.FullName == repl.typeName select y).Single(); if (repl.action == RewriteAction.Replace) { typeTarget._replacementType = t; } _typeRewrites.Add(typeRewrite = new TypeRewrite() { MemberInfo = t, Rewrite = repl, Graph = typeTarget }); } foreach (var m in t.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (forceImplRewrite) { if (m is MethodInfo) { _staticImplCache.Add(m as MethodInfo); } } var mRep = m.GetCustomAttribute <RewriteAttribute>(); if (mRep == null) { continue; } var mTypeTarget = mRep.typeName == null || (repl != null && repl.typeName == mRep.typeName) ? typeTarget : (from x in Graph.Modules from y in x.TypeGraphs where y.FullName == mRep.typeName select y).Single(); if (typeRewrite == null) { _typeRewrites.Add(typeRewrite = new TypeRewrite() { MemberInfo = t }); } var name = mRep.targetName ?? m.Name; if (m is MethodBase) { var mb = m as MethodBase; var target = mTypeTarget.Methods.FirstOrDefault(x => x.Name == name); MethodGraph newTarget = null; if (mRep.action == RewriteAction.Add) { newTarget = new MethodGraph(mb, mTypeTarget); } else if (mRep.action == RewriteAction.Remove) { target.DeclaringObject = null; } else if (mRep.action != RewriteAction.None) { newTarget = target.SwitchImpl(mb, mRep.newName, mRep.oldName); if (mRep.action == RewriteAction.Replace) { target.DeclaringObject = null; } else if (mRep.action == RewriteAction.Swap && newTarget.Name == target.Name) { target.Name += "_Orig"; } } if (mRep.contentHandler != null) { t.GetMethod(mRep.contentHandler).Invoke(null, new object[] { target, newTarget }); } typeRewrite.MethodRewrites.Add(new RewriteInfo <MethodBase, MethodGraph>() { MemberInfo = mb, Rewrite = mRep, Graph = mRep.action == RewriteAction.Replace || mRep.stubAction == StubAction.UseNew ? (newTarget ?? target) : (target ?? newTarget) }); } else if (m is PropertyInfo) { var p = m as PropertyInfo; var target = mTypeTarget.Properties.FirstOrDefault(x => x.Name == name); PropertyGraph newTarget = null; MethodGraph newGet = null, newSet = null; MethodGraph oldGet = null, oldSet = null; if (mRep.action == RewriteAction.Add) { newTarget = new PropertyGraph(p, mTypeTarget); if (newTarget._getAccessor != null) { newGet = new MethodGraph(newTarget._getAccessor, mTypeTarget); } if (newTarget._setAccessor != null) { newSet = new MethodGraph(newTarget._setAccessor, mTypeTarget); } } else { oldGet = target._getAccessor != null?mTypeTarget.Methods.FirstOrDefault(x => x._sourceObject == target._getAccessor) : null; oldSet = target._setAccessor != null?mTypeTarget.Methods.FirstOrDefault(x => x._sourceObject == target._setAccessor) : null; if (mRep.action == RewriteAction.Remove) { if (oldGet != null) { oldGet.DeclaringObject = null; } if (oldSet != null) { oldSet.DeclaringObject = null; } target.DeclaringObject = null; } else if (mRep.action != RewriteAction.None) { newTarget = new PropertyGraph(p, mTypeTarget); newTarget.Source = target.Source; if (newTarget._getAccessor != null) { newGet = oldGet.SwitchImpl(newTarget._getAccessor); } if (newTarget._setAccessor != null) { newSet = oldSet.SwitchImpl(newTarget._setAccessor); } if (mRep.action == RewriteAction.Replace) { if (oldGet != null) { oldGet.DeclaringObject = null; } if (oldSet != null) { oldSet.DeclaringObject = null; } target.DeclaringObject = null; } else if (mRep.action == RewriteAction.Swap && newTarget.Name == target.Name) { target.Name += "_Orig"; if (oldGet != null) { oldGet.Name += "_Orig"; } if (oldSet != null) { oldSet.Name += "_Orig"; } } } } if (mRep.contentHandler != null) { t.GetMethod(mRep.contentHandler).Invoke(null, new object[] { target, newTarget }); } typeRewrite.PropertyRewrites.Add(new PropertyRewrite() { MemberInfo = p, Rewrite = mRep, Graph = mRep.action == RewriteAction.Replace || mRep.stubAction == StubAction.UseNew ? (newTarget ?? target) : (target ?? newTarget), GetGraph = mRep.action == RewriteAction.Replace || mRep.stubAction == StubAction.UseNew ? (newGet ?? oldGet) : (oldGet ?? newGet), SetGraph = mRep.action == RewriteAction.Replace || mRep.stubAction == StubAction.UseNew ? (newSet ?? oldSet) : (oldSet ?? newSet) }); } else if (m is FieldInfo) { var f = m as FieldInfo; var target = mTypeTarget.Fields.FirstOrDefault(x => x.Name == name); FieldGraph newTarget = null; if (mRep.action == RewriteAction.Remove) { target.DeclaringObject = null; } else if (mRep.action != RewriteAction.None) { newTarget = new FieldGraph(f, mTypeTarget); if (mRep.action == RewriteAction.Replace) { newTarget.Source = target.Source; target.DeclaringObject = null; } else if (mRep.action == RewriteAction.Swap) { target.Name += "_Orig"; } } if (mRep.contentHandler != null) { t.GetMethod(mRep.contentHandler).Invoke(null, new object[] { target, newTarget }); } typeRewrite.FieldRewrites.Add(new RewriteInfo <FieldInfo, FieldGraph>() { MemberInfo = f, Rewrite = mRep, Graph = mRep.action == RewriteAction.Replace || mRep.stubAction == StubAction.UseNew ? (newTarget ?? target) : (target ?? newTarget) }); } } } }
public override async Task <IGenesisExecutionResult> Execute(GenesisContext genesis, string[] args) { Text.WhiteLine($"Downloading from [{Config.Address}]"); //https://swagger.io/docs/specification/basic-structure/ var gen = await OpenApiDocument.FromUrlAsync(Config.Address); gen.GenerateOperationIds(); var usings = new[] { "System", "System.Text", "System.Collections", "System.Collections.Generic", "System.Threading.Tasks", "System.Linq", "System.Net.Http", "System.ComponentModel.DataAnnotations", "Newtonsoft.Json", }; var settings = new CSharpClientGeneratorSettings { GenerateDtoTypes = true, AdditionalContractNamespaceUsages = usings, AdditionalNamespaceUsages = usings }; settings.CodeGeneratorSettings.InlineNamedAny = true; settings.CSharpGeneratorSettings.Namespace = Config.OutputNamespace; settings.CSharpGeneratorSettings.ClassStyle = CSharpClassStyle.Inpc; var generator = new NSwag.CodeGeneration.OperationNameGenerators.MultipleClientsFromFirstTagAndPathSegmentsOperationNameGenerator(); var csgen = new CSharpClientGenerator(gen, settings); csgen.Settings.GenerateOptionalParameters = true; csgen.Settings.GenerateResponseClasses = true; csgen.Settings.SerializeTypeInformation = true; csgen.Settings.OperationNameGenerator = generator; Text.White($"Processing contents... "); var code = csgen.GenerateFile(ClientGeneratorOutputType.Full); Text.GreenLine("OK"); var trustedAssembliesPaths = ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator); var neededLibs = new [] { "mscorlib", "netstandard", "System.Core", "System.Runtime", "System.IO", "System.ObjectModel", "System.Linq", "System.Net.Http", "System.Collections", "System.CodeDom.Compiler", "System.ComponentModel", "System.ComponentModel.Annotations", "System.Net.Primitives", "System.Runtime.Serialization", "System.Runtime.Serialization.Primitives", "System.Runtime.Extensions", "System.Private.Uri", "System.CodeDom", "System.Composition.AttributedModel", "System.Composition.Convention", "System.Composition.Runtime", "System.Diagnostics.Tools", "Microsoft.CodeAnalysis.CSharp", "NJsonSchema", "Newtonsoft.Json", }; Text.WhiteLine($"Determining dependencies"); var refs = trustedAssembliesPaths .Where(p => neededLibs.Contains(Path.GetFileNameWithoutExtension(p))) .Select(p => MetadataReference.CreateFromFile(p)) .ToList(); refs.Add(MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location)); var options = new CSharpParseOptions(LanguageVersion.CSharp8, DocumentationMode.Parse, SourceCodeKind.Regular); Text.WhiteLine("Defining entry point"); var rdr = new StringReader(code); var lines = new StringBuilder(); var i = 0; string line; while ((line = await rdr.ReadLineAsync()) != null) { lines.AppendLine(line); if (i == 26) //lol lame { lines.AppendLine(ENTRY_POINT); } i++; } code = lines.ToString(); File.WriteAllText(@"C:\Temp\GeneratedCode.cs", code); Text.WhiteLine("Creating Syntax Tree"); var syntax = CSharpSyntaxTree.ParseText(code, options: options); Text.WhiteLine("Preprocessing"); var comp = CSharpCompilation.Create("swag-gen-temp.dll", new[] { syntax }, refs.ToArray()); await using var stream = new MemoryStream(); Text.White("Creating temporary objects... "); var result = comp.Emit(stream); Text.GreenLine("OK"); if (!result.Success) { Text.RedLine("Unable to build temp library"); var failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); foreach (var diagnostic in failures) { Text.RedLine($@"\t{diagnostic.Id}: {diagnostic.GetMessage()}"); } return(new InputGenesisExecutionResult { Success = false, Message = "Errors occurred" }); } stream.Seek(0, SeekOrigin.Begin); var tmpAss = AssemblyLoadContext.Default.LoadFromStream(stream); // loop classes foreach (var c in tmpAss.GetTypes().Where(w => w.IsClass)) { Text.GrayLine($"Class: {c.Name}"); var obj = new ObjectGraph { Name = c.Name, Namespace = Config.OutputNamespace, GraphType = GraphTypes.Object, }; foreach (var p in c.GetProperties().Where(w => w.MemberType == MemberTypes.Property)) { if (!p.CanWrite || !p.GetSetMethod(/*nonPublic*/ true).IsPublic) { continue; //for now; } var pg = new PropertyGraph { Name = p.Name, SourceType = p.PropertyType.Name, IsKeyProperty = p.Name.EndsWith("Id", StringComparison.CurrentCultureIgnoreCase), //NOTE: cheesy Accesibility = (p.CanWrite && p.GetSetMethod(/*nonPublic*/ true).IsPublic) ? "public" : "protected" }; obj.Properties.Add(pg); Text.GrayLine($"\tProperty: {c.Name}"); } foreach (var m in c.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { var meth = new MethodGraph { Name = m.Name.Replace("get_", string.Empty), MethodVisibility = MethodVisibilities.Public, ReturnDataType = m.ReturnType, HasGenericParams = m.ContainsGenericParameters, IsGeneric = m.IsGenericMethod, }; foreach (var par in m.GetParameters().Where(w => w.IsIn).OrderBy(o => o.Position)) { var mp = new ParameterGraph { DataType = par.ParameterType, Name = par.Name, IsOut = par.IsOut, IsOptional = par.IsOptional, Position = par.Position }; meth.Parameters.Add(mp); Text.GrayLine($"\tMethod: {c.Name}"); } } genesis.Objects.Add(obj); } Text.SuccessGraffiti(); return(await base.Execute(genesis, args)); //TODO: fix the whole IGenesisExecutionResult "stuff" }
/// <summary> /// Translates a method to C#. /// </summary> /// <param name="m">Method to translate.</param> /// <returns>C# code for the method.</returns> public string TranslateMethod(MethodGraph m) { return(methodTranslator.Translate(m, true)); }