예제 #1
0
        public ReturnNode(MethodGraph graph)
            : base(graph)
        {
            AddInputExecPin("Exec");

            SetupSecondaryNodeEvents();
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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]);
        }
예제 #4
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]);
        }
예제 #5
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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
                        }
                    }
                }
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
                        }
                    }
                }
            }
        }
예제 #10
0
        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]);
        }
예제 #11
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);
            }
        }
예제 #12
0
        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]);
        }
예제 #13
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);
        }
예제 #14
0
        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") }));
        }
예제 #15
0
        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);
        }
예제 #16
0
        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;
            }
        }
예제 #17
0
        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);
        }
예제 #18
0
        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);
                }
            }
        }
예제 #19
0
 public DelayNode(MethodGraph graph) :
     base(graph)
 {
 }
예제 #20
0
 public MethodEntryNode(MethodGraph graph)
     : base(graph)
 {
     AddOutputExecPin("Exec");
 }
예제 #21
0
        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)
                        });
                    }
                }
            }
        }
예제 #22
0
        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"
        }
예제 #23
0
 /// <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));
 }