Beispiel #1
0
        public virtual RulesBasedParser build()
        {
            RulesBasedParser rulesBasedParser = new RulesBasedParser();

            // decide what to show
            AAction.displaySemi  = false;
            AAction.displayStack = false;              // false is default

            // action used for namespaces, classes, and functions
            PushStack push = new PushStack(Repo);

            // capture namespace info
            DetectNamespace detectNS = new DetectNamespace();

            detectNS.add(push);
            rulesBasedParser.add(detectNS);

            // capture class info
            DetectClass detectCl = new DetectClass();

            detectCl.add(push);
            rulesBasedParser.add(detectCl);

            // capture function info
            DetectFunction detectFN = new DetectFunction(Repo);

            detectFN.add(push);
            rulesBasedParser.add(detectFN);

            // handle entering anonymous scopes, e.g., if, while, etc.
            DetectAnonymousScope anon = new DetectAnonymousScope();

            anon.add(push);
            rulesBasedParser.add(anon);

            // handle leaving scopes
            DetectLeavingScope leave = new DetectLeavingScope();
            PopStack           pop   = new PopStack(Repo);

            leave.add(pop);
            rulesBasedParser.add(leave);

            // save class member variables
            var detectMembers  = new DetectMemberVariable(Repo);
            var addClassMember = new AddClassMember(Repo);

            detectMembers.add(addClassMember);
            rulesBasedParser.add(detectMembers);

            // rulesBasedParser configured
            return(rulesBasedParser);
        }
        public virtual RulesBasedParser build()
        {
            RulesBasedParser rulesBasedParser = new RulesBasedParser();

            // decide what to show
            AAction.displaySemi  = false;
            AAction.displayStack = false;              // false is default

            // action used for namespaces, locations, and functions
            PushStack push = new PushStack(Repo);

            // capture class dependencies
            var detectDeps  = new DetectClassDependency(Repo, _locations);
            var addClassDep = new AddClassDependency(Repo);

            detectDeps.add(addClassDep);
            rulesBasedParser.add(detectDeps);

            var detectMemberUsage = new DetectMemberUsage(Repo, _classMembers);
            var addMemberUsage    = new AddMemberUsage(Repo);

            detectMemberUsage.add(addMemberUsage);
            rulesBasedParser.add(detectMemberUsage);

            // capture namespace info
            DetectNamespace detectNS = new DetectNamespace();

            detectNS.add(push);
            rulesBasedParser.add(detectNS);

            // capture class info
            DetectClass detectCl = new DetectClass();

            detectCl.add(push);
            rulesBasedParser.add(detectCl);

            // capture function info
            DetectFunction detectFN = new DetectFunction(Repo);

            detectFN.add(push);
            rulesBasedParser.add(detectFN);

            // handle leaving scopes
            DetectLeavingScope leave = new DetectLeavingScope();
            PopStack           pop   = new PopStack(Repo);

            leave.add(pop);
            rulesBasedParser.add(leave);

            // rulesBasedParser configured
            return(rulesBasedParser);
        }
        public static IEnumerable <ElementProperty> ParseFiles(IEnumerable <string> files, MIndexOptions mIndexOptions = null)
        {
            var firstPassLocations = new List <Elem>();
            var dependencies       = new Dictionary <string, List <string> >();
            var classMembers       = new Dictionary <string, List <string> >();
            var functionMembers    = new Dictionary <(string Class, string Method), List <string> >();

            foreach (var file in files)
            {
                CSemiExp semi = new CSemiExp();
                semi.displayNewLines = false;
                if (!semi.open(file))
                {
                    throw new ArgumentException($"Cannot open file {file}");
                }

                var firstPassCodeAnalyzer        = new RulesBasedParserOne(semi);
                RulesBasedParser firstPassParser = firstPassCodeAnalyzer.build();

                while (semi.getSemi())
                {
                    firstPassParser.parse(semi);
                }
                semi.close();

                var firstRepo = firstPassCodeAnalyzer?.GetRepository();
                firstPassLocations.AddRange(firstRepo.locations);
                foreach (var member in firstRepo.ClassMembers)
                {
                    classMembers[member.Key] = member.Value;
                }
            }

            foreach (var file in files)
            {
                CSemiExp semi = new CSemiExp();
                semi.displayNewLines = false;
                if (!semi.open(file))
                {
                    throw new ArgumentException($"Cannot open file {file}");
                }

                var secondPassCodeAnalyzer        = new RulesBasedParserTwo(semi, firstPassLocations, classMembers);
                RulesBasedParser secondPassParser = secondPassCodeAnalyzer.build();

                while (semi.getSemi())
                {
                    secondPassParser.parse(semi);
                }
                semi.close();

                var secondRepo = secondPassCodeAnalyzer?.GetRepository();
                foreach (var dependency in secondRepo.ClassDependencies)
                {
                    dependencies[dependency.Key] = dependency.Value;
                }
                foreach (var member in secondRepo.FunctionMembers)
                {
                    functionMembers[member.Key] = member.Value;
                }
            }

            var elements = firstPassLocations
                           .Select(e => new ElementProperty
            {
                Type                 = e.type,
                Name                 = e.name,
                FunctionClass        = e.functionClass,
                LinesOfCode          = e.endLine - e.beginLine,
                CyclomaticComplexity = e.endScopeCount - e.beginScopeCount + 1
            })
                           .ToList();

            var newElements = new List <ElementProperty>();

            foreach (var e in elements)
            {
                if (e.Type == "class")
                {
                    // Class members
                    if (classMembers.ContainsKey(e.Name))
                    {
                        e.Members = classMembers[e.Name];
                    }

                    // Class dependencies
                    if (dependencies.ContainsKey(e.Name))
                    {
                        foreach (var d in dependencies[e.Name])
                        {
                            var element = elements.First(el => el.Name == d);
                            e.Dependencies.Add(element);
                        }
                    }
                }
                else if (e.Type == "function" && functionMembers.ContainsKey((e.FunctionClass, e.Name)))
                {
                    e.Members = functionMembers[(e.FunctionClass, e.Name)];