示例#1
0
        public void TestEmpty()
        {
            var root = new Program(
                new Core.Lexer.Range(new StringLocation(0), new StringLocation(1)),
                new List <StructDeclaration>(),
                new List <FunctionDeclaration>());
            var graph = new Dictionary <FunctionDeclaration, IReadOnlyCollection <VariableDeclaration> >();

            var resultExpected = new Dictionary <Node, IReadOnlyCollection <VariableDeclaration> >()
            {
                { root, new List <VariableDeclaration>() }
            };

            var callGraphGenerator = new CallGraphGenerator();
            var nodeInfoExtractors = new Dictionary <VariableInfo, INodeInfoExtractor>
            {
                [VariableInfo.Access]        = new AccessInfoExtractor(),
                [VariableInfo.Modifications] = new ModifyInfoExtractor(),
            };
            var generator    = new VariableAccessGraphGenerator(callGraphGenerator, nodeInfoExtractors);
            var resultActual = generator.GetVariableInfoPerAstNode(root);

            MappingEquivalence.AssertAreEquivalentCollection(resultExpected, resultActual.Accesses);
            MappingEquivalence.AssertAreEquivalentCollection(resultExpected, resultActual.Modifies);
        }
示例#2
0
        public IVariableAccessGraphGenerator GetGenerator()
        {
            var callGraphGenerator = new CallGraphGenerator();
            var nodeInfoExtractors = new Dictionary <VariableInfo, INodeInfoExtractor>
            {
                [VariableInfo.Access]        = new AccessInfoExtractor(),
                [VariableInfo.Modifications] = new ModifyInfoExtractor(),
            };

            return(new VariableAccessGraphGenerator(callGraphGenerator, nodeInfoExtractors));
        }
示例#3
0
        public void TestCallGraph()
        {
            var names = new List <string> {
                "a", "b", "c"
            };
            var functions = new List <FunctionDeclaration>();
            var calls     = new List <FunctionCall>();

            foreach (var id in names)
            {
                var functionCall = new FunctionCall(
                    new Range(new StringLocation(0), new StringLocation(1)),
                    "b",
                    new List <Expression>());
                calls.Add(functionCall);
                var body = new InstructionBlock(
                    new Range(new StringLocation(0), new StringLocation(1)),
                    new List <Expression> {
                    functionCall
                });
                var fun = new FunctionDeclaration(
                    new Range(new StringLocation(0), new StringLocation(1)),
                    id,
                    UnitType.Instance,
                    new List <VariableDeclaration>(),
                    body,
                    false);
                functions.Add(fun);
            }

            foreach (var call in calls)
            {
                call.Declaration = functions[1];
            }

            var root = new Program(
                new Range(new StringLocation(0), new StringLocation(1)),
                new List <StructDeclaration>(),
                functions);

            CallGraphGenerator gen = new CallGraphGenerator();
            var dict = gen.BuildCallGraph(root);

            Assert.AreEqual(1, dict[functions[0]].Count);
            Assert.AreEqual(1, dict[functions[1]].Count);
            Assert.AreEqual(1, dict[functions[2]].Count);

            Assert.IsTrue(dict[functions[0]].Contains(functions[1]));
            Assert.IsTrue(dict[functions[1]].Contains(functions[1]));
            Assert.IsTrue(dict[functions[2]].Contains(functions[1]));
        }
示例#4
0
        public void TestComplex()
        {
            /* Build AST */

            var declarationX = AstConstructionUtils.CreateVariableDeclaration("x");
            var declarationY = AstConstructionUtils.CreateVariableDeclaration("y");

            var assignmentX = AstConstructionUtils.CreateAssignment(
                declarationX,
                AstConstructionUtils.CreateVariable(declarationY));
            var incrementY = AstConstructionUtils.CreateIncrement(declarationY);

            var funInner = AstConstructionUtils.CreateFunction(
                "funInner",
                new List <Expression> {
                assignmentX
            });

            var funOuter = AstConstructionUtils.CreateFunction(
                "funOuter",
                new List <Expression> {
                declarationX, declarationY, incrementY, funInner
            });

            var functions = new List <FunctionDeclaration> {
                funOuter
            };
            var root = new Program(
                new Core.Lexer.Range(new StringLocation(0), new StringLocation(1)),
                new List <StructDeclaration>(),
                functions);

            /* Prepare graphs */

            var accessGraph = new Dictionary <FunctionDeclaration, IReadOnlyCollection <VariableDeclaration> >()
            {
                { funInner, new List <VariableDeclaration> {
                      declarationX, declarationY
                  } },
                { funOuter, new List <VariableDeclaration> {
                      declarationY
                  } }
            };

            var modificationGraph = new Dictionary <FunctionDeclaration, IReadOnlyCollection <VariableDeclaration> >()
            {
                { funInner, new List <VariableDeclaration> {
                      declarationX
                  } },
                { funOuter, new List <VariableDeclaration> {
                      declarationY
                  } }
            };

            /* Compute accesses per node */

            var accessNothing = new List <Node>
            {
                root, funInner, funOuter, declarationX, declarationY,
                declarationX.Value, declarationY.Value, incrementY.Value
            };

            var accessX = new List <Node> {
                assignmentX.Lhs
            };
            var accessY = new List <Node> {
                funOuter.Body, incrementY, incrementY.Lhs, assignmentX.Value
            };
            var accessBoth = new List <Node> {
                assignmentX, funInner.Body
            };

            var expectedAccesses = new Dictionary <Node, IReadOnlyCollection <VariableDeclaration> >();

            foreach (var node in accessNothing)
            {
                expectedAccesses[node] = new List <VariableDeclaration>();
            }

            foreach (var node in accessX)
            {
                expectedAccesses[node] = new List <VariableDeclaration> {
                    declarationX
                };
            }

            foreach (var node in accessY)
            {
                expectedAccesses[node] = new List <VariableDeclaration> {
                    declarationY
                };
            }

            foreach (var node in accessBoth)
            {
                expectedAccesses[node] = new List <VariableDeclaration> {
                    declarationX, declarationY
                };
            }

            /* Compute modifications per node */

            var modifyNothing = new List <Node>
            {
                root, funInner, funOuter, declarationX, declarationY, assignmentX.Lhs, assignmentX.Value,
                declarationX.Value, declarationY.Value, incrementY.Value, incrementY.Lhs
            };

            var modifyX = new List <Node> {
                funInner.Body, assignmentX
            };
            var modifyY = new List <Node> {
                funOuter.Body, incrementY
            };

            var expectedModifications = new Dictionary <Node, IReadOnlyCollection <VariableDeclaration> >();

            foreach (var node in modifyNothing)
            {
                expectedModifications[node] = new List <VariableDeclaration>();
            }

            foreach (var node in modifyX)
            {
                expectedModifications[node] = new List <VariableDeclaration> {
                    declarationX
                };
            }

            foreach (var node in modifyY)
            {
                expectedModifications[node] = new List <VariableDeclaration> {
                    declarationY
                };
            }

            /* Get results from generator and compare */

            var callGraphGenerator = new CallGraphGenerator();
            var nodeInfoExtractors = new Dictionary <VariableInfo, INodeInfoExtractor>
            {
                [VariableInfo.Access]        = new AccessInfoExtractor(),
                [VariableInfo.Modifications] = new ModifyInfoExtractor(),
            };
            var generator    = new VariableAccessGraphGenerator(callGraphGenerator, nodeInfoExtractors);
            var resultActual = generator.GetVariableInfoPerAstNode(root);

            MappingEquivalence.AssertAreEquivalentCollection(expectedAccesses, resultActual.Accesses);
            MappingEquivalence.AssertAreEquivalentCollection(expectedModifications, resultActual.Modifies);
        }
示例#5
0
        public void TestInnerFunction()
        {
            var functions = new List <FunctionDeclaration>();
            var aCall     = new FunctionCall(
                new Range(new StringLocation(0), new StringLocation(1)),
                "a",
                new List <Expression>());
            var instructionBlock = new InstructionBlock(
                new Range(new StringLocation(0), new StringLocation(1)),
                new List <Expression> {
                aCall
            });
            var b = new FunctionDeclaration(
                new Range(new StringLocation(0), new StringLocation(1)),
                "b",
                UnitType.Instance,
                new List <VariableDeclaration>(),
                instructionBlock,
                false);

            functions.Add(b);

            var cCall = new FunctionCall(
                new Range(new StringLocation(0), new StringLocation(1)),
                "c",
                new List <Expression>());

            var block = new InstructionBlock(
                new Range(new StringLocation(0), new StringLocation(1)),
                new List <Expression> {
                cCall
            });
            var c = new FunctionDeclaration(
                new Range(new StringLocation(0), new StringLocation(1)),
                "c",
                UnitType.Instance,
                new List <VariableDeclaration>(),
                block,
                false);

            var bCall = new FunctionCall(
                new Range(new StringLocation(0), new StringLocation(1)),
                "b",
                new List <Expression>());

            var body = new InstructionBlock(
                new Range(new StringLocation(0), new StringLocation(1)),
                new List <Expression> {
                bCall, c
            });
            var a = new FunctionDeclaration(
                new Range(new StringLocation(0), new StringLocation(1)),
                "a",
                UnitType.Instance,
                new List <VariableDeclaration>(),
                body,
                false);

            functions.Add(a);

            var root = new Program(
                new Range(new StringLocation(0), new StringLocation(1)),
                new List <StructDeclaration>(),
                new List <FunctionDeclaration> {
                a, b
            });

            aCall.Declaration = a;
            bCall.Declaration = b;
            cCall.Declaration = c;

            CallGraphGenerator gen = new CallGraphGenerator();
            var dict = gen.BuildCallGraph(root);

            Assert.AreEqual(1, dict[b].Count);
            Assert.AreEqual(1, dict[a].Count);
            Assert.AreEqual(1, dict[c].Count);

            Assert.IsTrue(dict[b].Contains(a));
            Assert.IsTrue(dict[c].Contains(c));
            Assert.IsTrue(dict[a].Contains(b));
        }