<commit_before>﻿// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the MIT License.  See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.FindSymbols;
using Orleans;
using OrleansInterfaces;
using ReachingTypeAnalysis.Analysis;
using ReachingTypeAnalysis.Communication;
using ReachingTypeAnalysis.Roslyn;
using SolutionTraversal.Callgraph;
using Microsoft.CodeAnalysis.MSBuild;

namespace ReachingTypeAnalysis
{
    public enum AnalysisStrategyKind
    {
        ONDEMAND_SYNC,
        ENTIRE_SYNC,
        ONDEMAND_ASYNC,
        ONDEMAND_ORLEANS,
        ENTIRE_ASYNC,
        NONE,
    }

	public class SolutionAnalyzer
	{
		// Just for text
		internal Solution Solution { get; private set; }

		internal IDispatcher Dispatcher { get; private set; }

        internal string SourceCode { get; private set; }
		public SolutionAnalyzer(Solution solution)
		{
			this.Solution = solution;
			//dispatcher = new SynchronousLocalDispatcher();
		}

        public SolutionAnalyzer(string sourceCode)
        {
            this.Solution = Utils.CreateSolution(sourceCode);
            this.SourceCode = sourceCode;
            //dispatcher = new SynchronousLocalDispatcher();
        }

        public static SolutionAnalyzer CreateFromSolutionFile(string solutionFileName)
        {
            var solutionName = Path.GetFileName(solutionFileName);
            Console.WriteLine("Loading solution {0}...", solutionName);
            var props = new Dictionary<string, string>();
            props["CheckForSystemRuntimeDependency"] = "true";
            var ws = MSBuildWorkspace.Create(props);
            var solution = ws.OpenSolutionAsync(solutionFileName).Result;
            Console.WriteLine("Solution loaded successfully", solutionName);

            return new SolutionAnalyzer(solution);
        }


		/// <summary>
		/// IMPORTANT: OnDemandSolvers need an OnDemand Dispatcher
		/// We cannot use the SyncronousDistacther because it doesn't look for the 
		/// methods when they are not available. This only works with the entire solution
		/// analysis!!!!
		/// </summary>
		/// <param name="dispatcher"></param>
        public CallGraph<MethodDescriptor, LocationDescriptor>
            Analyze(AnalysisStrategyKind strategyKind = AnalysisStrategyKind.NONE, bool produceCallGraph = true)
        {
            if (strategyKind == AnalysisStrategyKind.NONE)
            {
                strategyKind = StringToAnalysisStrategy(ConfigurationManager.AppSettings["Strategy"]);
            }

            // TOOD: hack -- set the global solution
            ProjectCodeProvider.Solution = this.Solution;

            switch (strategyKind)
            {
                case AnalysisStrategyKind.ONDEMAND_SYNC:
                    {
                        this.Dispatcher = new OnDemandSyncDispatcher();
                        AnalyzeOnDemand();
                        return this.GenerateCallGraph();
                    }
                case AnalysisStrategyKind.ENTIRE_SYNC:
                    {
                        this.Dispatcher = new SynchronousLocalDispatcher();
                        AnalyzeEntireSolution();

                        return this.GenerateCallGraph();
                    }
                case AnalysisStrategyKind.ONDEMAND_ASYNC:
                    {
						//this.Dispatcher = new AsyncDispatcher();
						this.Dispatcher = null;

						this.Strategy = new OnDemandAsyncStrategy(this.Solution);
						var solutionManager = new SolutionManager(this.Solution);
						var mainMethods = solutionManager.GetRoots().Result;
						var orchestator = new AnalysisOrchestator(Strategy);
						orchestator.AnalyzeAsync(mainMethods).Wait();

						//var compilerMainMethod = new MethodDescriptor("Microsoft.CodeAnalysis.CSharp.CommandLine", "Program", "Main", true);
						//Console.WriteLine("Analyzing {0}...", compilerMainMethod.Name);
						//orchestator.AnalyzeAsync(compilerMainMethod).Wait();

						var callGraph = orchestator.GenerateCallGraphAsync(solutionManager).Result;
	                    return callGraph;
                    }
                case AnalysisStrategyKind.ONDEMAND_ORLEANS:
					{
						/*<commit_msg>Adding comment<commit_after>﻿// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the MIT License.  See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.FindSymbols;
using Orleans;
using OrleansInterfaces;
using ReachingTypeAnalysis.Analysis;
using ReachingTypeAnalysis.Communication;
using ReachingTypeAnalysis.Roslyn;
using SolutionTraversal.Callgraph;
using Microsoft.CodeAnalysis.MSBuild;

namespace ReachingTypeAnalysis
{
    public enum AnalysisStrategyKind
    {
        ONDEMAND_SYNC,
        ENTIRE_SYNC,
        ONDEMAND_ASYNC,
        ONDEMAND_ORLEANS,
        ENTIRE_ASYNC,
        NONE,
    }

	public class SolutionAnalyzer
	{
		// Just for text
		internal Solution Solution { get; private set; }

		internal IDispatcher Dispatcher { get; private set; }

        internal string SourceCode { get; private set; }
		public SolutionAnalyzer(Solution solution)
		{
			this.Solution = solution;
			//dispatcher = new SynchronousLocalDispatcher();
		}

        public SolutionAnalyzer(string sourceCode)
        {
            this.Solution = Utils.CreateSolution(sourceCode);
            this.SourceCode = sourceCode;
            //dispatcher = new SynchronousLocalDispatcher();
        }

        public static SolutionAnalyzer CreateFromSolutionFile(string solutionFileName)
        {
            var solutionName = Path.GetFileName(solutionFileName);
            Console.WriteLine("Loading solution {0}...", solutionName);
            var props = new Dictionary<string, string>();
            props["CheckForSystemRuntimeDependency"] = "true";
            var ws = MSBuildWorkspace.Create(props);
            var solution = ws.OpenSolutionAsync(solutionFileName).Result;
            Console.WriteLine("Solution loaded successfully", solutionName);

            return new SolutionAnalyzer(solution);
        }


		/// <summary>
		/// IMPORTANT: OnDemandSolvers need an OnDemand Dispatcher
		/// We cannot use the SyncronousDistacther because it doesn't look for the 
		/// methods when they are not available. This only works with the entire solution
		/// analysis!!!!
		/// </summary>
		/// <param name="dispatcher"></param>
        public CallGraph<MethodDescriptor, LocationDescriptor>
            Analyze(AnalysisStrategyKind strategyKind = AnalysisStrategyKind.NONE, bool produceCallGraph = true)
        {
            if (strategyKind == AnalysisStrategyKind.NONE)
            {
                strategyKind = StringToAnalysisStrategy(ConfigurationManager.AppSettings["Strategy"]);
            }

            // TOOD: hack -- set the global solution
            ProjectCodeProvider.Solution = this.Solution;

            switch (strategyKind)
            {
                case AnalysisStrategyKind.ONDEMAND_SYNC:
                    {
                        this.Dispatcher = new OnDemandSyncDispatcher();
                        AnalyzeOnDemand();
                        return this.GenerateCallGraph();
                    }
                case AnalysisStrategyKind.ENTIRE_SYNC:
                    {
                        this.Dispatcher = new SynchronousLocalDispatcher();
                        AnalyzeEntireSolution();

                        return this.GenerateCallGraph();
                    }
                case AnalysisStrategyKind.ONDEMAND_ASYNC:
                    {
						//this.Dispatcher = new AsyncDispatcher();
						this.Dispatcher = null;

						this.Strategy = new OnDemandAsyncStrategy(this.Solution);
						var solutionManager = new SolutionManager(this.Solution);
						var mainMethods = solutionManager.GetRoots().Result;
						var orchestator = new AnalysisOrchestator(Strategy);
						orchestator.AnalyzeAsync(mainMethods).Wait();

						// This is for debugging just one project
						//var compilerMainMethod = new MethodDescriptor("Microsoft.CodeAnalysis.CSharp.CommandLine", "Program", "Main", true);
						//Console.WriteLine("Analyzing {0}...", compilerMainMethod.Name);
						//orchestator.AnalyzeAsync(compilerMainMethod).Wait();

						var callGraph = orchestator.GenerateCallGraphAsync(solutionManager).Result;
	                    return callGraph;
                    }
                case AnalysisStrategyKind.ONDEMAND_ORLEANS:
					{
						/*
{'fraction_non_alphanumeric': 0.08274628200827462, 'fraction_numerical': 0.00044727720004472774, 'mean_word_length': 2.447956823438705, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6978879', 'n_tokens_mistral': 2445, 'n_tokens_neox': 2149, 'n_words': 520}