예제 #1
0
		protected override async Task<EvaluationResult> EvaluateImpl(SyntaxNode node, SemanticModel semanticModel, Solution solution)
		{
			var symbol = (ITypeSymbol)semanticModel.GetDeclaredSymbol(node);
			var efferent = GetReferencedTypes(node, symbol, semanticModel).AsArray();
			var awaitable = SymbolFinder.FindCallersAsync(symbol, solution, CancellationToken.None).ConfigureAwait(false);
			var callers = (await awaitable).AsArray();
			var testCallers = callers
				.Where(c => c.CallingSymbol.GetAttributes()
				.Any(x => x.AttributeClass.Name.IsKnownTestAttribute()))
				.AsArray();
			var afferent = callers.Except(testCallers)
				.Select(x => x.CallingSymbol.ContainingType)
				.DistinctBy(s => s.ToDisplayString())
				.AsArray();

			var efferentLength = (double)efferent.Length;
			var stability = efferentLength / (efferentLength + afferent.Length);
			if (stability >= 0.8)
			{
				return new EvaluationResult
				{
					ImpactLevel = ImpactLevel.Project,
					Quality = CodeQuality.NeedsReview,
					QualityAttribute = QualityAttribute.CodeQuality | QualityAttribute.Conformance,
					Snippet = node.ToFullString()
				};
			}

			return null;
		}
예제 #2
0
        public IPersistentStorage GetStorage(Solution solution)
        {
            if (!ShouldUseEsent(solution))
            {
                return NoOpPersistentStorageInstance;
            }

            // can't use cached information
            if (!string.Equals(solution.FilePath, _lastSolutionPath, StringComparison.OrdinalIgnoreCase))
            {
                // check whether the solution actually exist on disk
                if (!File.Exists(solution.FilePath))
                {
                    return NoOpPersistentStorageInstance;
                }
            }

            // cache current result.
            _lastSolutionPath = solution.FilePath;

            // get working folder path
            var workingFolderPath = GetWorkingFolderPath(solution);
            if (workingFolderPath == null)
            {
                // we don't have place to save esent file. don't use esent
                return NoOpPersistentStorageInstance;
            }

            return GetStorage(solution, workingFolderPath);
        }
        public static Task<ImmutableArray<PatternSearchResult>> RunAsync(Solution solution, ImmutableArray<PatternSearch> searches)
        {
            if (solution == null)
                throw new ArgumentNullException(nameof(solution));

            return RunAsync(solution.Projects, searches);
        }
 public TestListCategorizer(string pathToVsmdiFile, string pathToSolution)
 {
     _workspace = MSBuildWorkspace.Create();
     _solution = _workspace.OpenSolutionAsync(pathToSolution).Result;
     var vsmdiParser = new VsmdiParser();
     _testlists = vsmdiParser.ReadFile(pathToVsmdiFile);
 }
 public void LoadInitialSemanticVersions(Solution solution)
 {
     foreach (var project in solution.Projects)
     {
         LoadInitialSemanticVersions(project);
     }
 }
예제 #6
0
 public SolutionAnalayzer(string solutionPath)
 {
     _workspace = MSBuildWorkspace.Create();
     _workspace.WorkspaceFailed += _workspace_WorkspaceFailed;
     _solution = _workspace.OpenSolutionAsync(solutionPath).Result;
     _refsourceLinkProvider.Init();
 }
 public MemberTarget(SourceTextContainer textContainer, ISymbol memberIdentifier, Project project, Solution solution)
 {
     _textContainer = textContainer;
     _memberIdentifier = memberIdentifier;
     _project = project;
     _solution = solution;
 }
            private async Task<Solution> RenameFields(Solution solution, DocumentId documentId, int count, CancellationToken cancellationToken)
            {
                Solution oldSolution = null;
                for (int i = 0; i < count; i++)
                {
                    oldSolution = solution;

                    var semanticModel = await solution.GetDocument(documentId).GetSemanticModelAsync(cancellationToken);
                    var root = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken);
                    var declaration = root.GetAnnotatedNodes(s_markerAnnotation).ElementAt(i);

                    // Make note, VB represents "fields" marked as "WithEvents" as properties, so don't be
                    // tempted to treat this as a IFieldSymbol. We only need the name, so ISymbol is enough.
                    var fieldSymbol = semanticModel.GetDeclaredSymbol(declaration, cancellationToken);
                    var newName = GetNewFieldName(fieldSymbol);

                    // Can happen with pathologically bad field names like _
                    if (newName == fieldSymbol.Name)
                    {
                        continue;
                    }

                    solution = await Renamer.RenameSymbolAsync(solution, fieldSymbol, newName, solution.Workspace.Options, cancellationToken).ConfigureAwait(false);
                    solution = await CleanSolutionAsync(solution, oldSolution, cancellationToken);
                }

                return solution;
            }
        internal static async Task<ImmutableList<CodeFixEquivalenceGroup>> CreateAsync(CodeFixProvider codeFixProvider, IEnumerable<Diagnostic> allDiagnostics, Solution solution)
        {
            var fixAllProvider = codeFixProvider.GetFixAllProvider();

            var relevantDiagnostics = allDiagnostics.Where(diagnostic => codeFixProvider.FixableDiagnosticIds.Contains(diagnostic.Id)).ToImmutableArray();

            if (fixAllProvider == null)
            {
                return ImmutableList.Create<CodeFixEquivalenceGroup>();
            }

            List<CodeAction> actions = new List<CodeAction>();

            foreach (var diagnostic in relevantDiagnostics)
            {
                actions.AddRange(await GetFixesAsync(solution, codeFixProvider, diagnostic).ConfigureAwait(false));
            }

            List<CodeFixEquivalenceGroup> groups = new List<CodeFixEquivalenceGroup>();

            foreach (var item in actions.GroupBy(x => x.EquivalenceKey))
            {
                groups.Add(new CodeFixEquivalenceGroup(item.Key, solution, fixAllProvider, codeFixProvider, relevantDiagnostics));
            }

            return groups.ToImmutableList();
        }
예제 #10
0
 public override void DisplayReferencedSymbols(Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols)
 {
     foreach (var presenter in _referencedSymbolsPresenters)
     {
         presenter.Value.DisplayResult(solution, referencedSymbols);
     }
 }
예제 #11
0
        public async Task<GraphBuilder> GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken)
        {
            var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false);

            foreach (var node in context.InputNodes)
            {
                var symbol = graphBuilder.GetSymbol(node);
                var references = await SymbolFinder.FindReferencesAsync(symbol, solution, cancellationToken).ConfigureAwait(false);

                foreach (var reference in references)
                {
                    var referencedSymbol = reference.Definition;
                    var projectId = graphBuilder.GetContextProject(node).Id;

                    var allLocations = referencedSymbol.Locations.Concat(reference.Locations.Select(r => r.Location))
                                                                 .Where(l => l != null && l.IsInSource);

                    foreach (var location in allLocations)
                    {
                        var locationNode = GetLocationNode(referencedSymbol, location, context, projectId, cancellationToken);
                        graphBuilder.AddLink(node, CodeLinkCategories.SourceReferences, locationNode);
                    }
                }
            }

            return graphBuilder;
        }
			public LookupResult (ISymbol symbol, Solution solution, Compilation compilation)
			{
				this.Success = true;
				this.Symbol = symbol;
				this.Solution = solution;
				this.Compilation = compilation;
			}
        protected Task RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind kind, Solution oldSolution, Solution newSolution, ProjectId projectId = null, DocumentId documentId = null)
        {
            if (newSolution == null)
            {
                throw new ArgumentNullException(nameof(newSolution));
            }

            if (oldSolution == newSolution)
            {
                return SpecializedTasks.EmptyTask;
            }

            if (projectId == null && documentId != null)
            {
                projectId = documentId.ProjectId;
            }

            var ev = _eventMap.GetEventHandlers<EventHandler<WorkspaceChangeEventArgs>>(WorkspaceChangeEventName);
            if (ev.HasHandlers)
            {
                return this.ScheduleTask(() =>
                {
                    var args = new WorkspaceChangeEventArgs(kind, oldSolution, newSolution, projectId, documentId);
                    ev.RaiseEvent(handler => handler(this, args));
                }, "Workspace.WorkspaceChanged");
            }
            else
            {
                return SpecializedTasks.EmptyTask;
            }
        }
예제 #14
0
 public Solution PreviewChanges(
     string title,
     string helpString,
     string description,
     string topLevelName,
     Glyph topLevelGlyph,
     Solution newSolution,
     Solution oldSolution,
     bool showCheckBoxes = true)
 {
     var engine = new PreviewEngine(
         title,
         helpString,
         description,
         topLevelName,
         topLevelGlyph,
         newSolution,
         oldSolution,
         _componentModel,
         _imageService,
         showCheckBoxes);
     _previewChanges.PreviewChanges(engine);
     engine.CloseWorkspace();
     return engine.FinalSolution;
 }
예제 #15
0
        protected Task RaiseWorkspaceChangedEventAsync(WorkspaceChangeKind kind, Solution oldSolution, Solution newSolution, ProjectId projectId = null, DocumentId documentId = null)
        {
            if (newSolution == null)
            {
                throw new ArgumentNullException("newSolution");
            }

            if (oldSolution == newSolution)
            {
                return SpecializedTasks.EmptyTask;
            }

            if (projectId == null && documentId != null)
            {
                projectId = documentId.ProjectId;
            }

            var handlers = this.eventMap.GetEventHandlers<EventHandler<WorkspaceChangeEventArgs>>(WorkspaceChangeEventName);
            if (handlers.Length > 0)
            {
                return this.ScheduleTask(() =>
                {
                    var args = new WorkspaceChangeEventArgs(kind, oldSolution, newSolution, projectId, documentId);
                    foreach (var handler in handlers)
                    {
                        handler(this, args);
                    }
                }, "Workspace.WorkspaceChanged");
            }
            else
            {
                return SpecializedTasks.EmptyTask;
            }
        }
예제 #16
0
        public SyntaxWalker(Solution solution, string project)
        {
            if (solution == null) throw new ArgumentException("solution");
            if (project == null) throw new ArgumentException("classProject");

            var solutionTrees = solution.GetTrees();
            _solutionCompilation = CSharpCompilation.Create("SolutionCompilation")
                .AddSyntaxTrees(solutionTrees)
                .WithReferences(new List<MetadataReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                    MetadataReference.CreateFromFile(typeof(IEnumerable).Assembly.Location),
                    MetadataReference.CreateFromFile(typeof(Task).Assembly.Location)
                });

            _allTrees = solution.GetTrees(new[] {project}).ToList();
            _projectCompilation = CSharpCompilation.Create("ProjectCompilation")
                .AddSyntaxTrees(_allTrees)
                .WithReferences(new List<MetadataReference>()
                {
                    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                    MetadataReference.CreateFromFile(typeof(IEnumerable).Assembly.Location),
                    MetadataReference.CreateFromFile(typeof(Task).Assembly.Location)
                });
        }
 public static ProjectMethod FindMethodSymbolAndProjectInSolution(Solution solution, MethodDescriptor methodDescriptor)
 {
     ProjectMethod res;
     res.Method = null;
     res.Project = null;
     foreach (var project in solution.Projects)
     {
         // Alternative method using SymbolFinder, it only works with methods in the solution
         // Discarded by the moment
         //var methodDeclarations = SymbolFinder.FindDeclarationsAsync(project, methodDescriptor.MethodName,false).Result;
         //methodDeclarations = methodDeclarations.Where(ms => methodDescriptor.SameAsMethodSymbom(ms as IMethodSymbol));
         //if (methodDeclarations.Count() > 0)
         //{
         //    return methodDeclarations.First() as IMethodSymbol;
         //}
         //else
         //{
         // My own method
         var method = FindMethodSymbolInProject(methodDescriptor, project);
         if (method != null)
         {
             res.Project = project;
             res.Method = method;
             return res;
         }
         //}
     }
     return res;
 }
        private async Task<List<ProjectAnalysisResult>> AnalyseSolutionAsync(Solution solution, ImmutableArray<DiagnosticAnalyzer> analyzers, Configuration configuration)
        {
            var ruleIds = analyzers
                .SelectMany(a => a.SupportedDiagnostics.Select(d => d.Id))
                .Where(d => !_configuration.DisabledDiagnostics.Contains(d))
                .ToImmutableHashSet();

            var projectAnalysisTasks = solution.Projects
                // First, Running analysis
                .Select(p => new { Project = p, Task = AnalyzeProjectAsync(p, analyzers) })
                .ToList()
                // Then we need to print all the results
                .Select(p => new { Project = p.Project, Task = p.Task.ContinueWith(t =>
                    {
                        var diagnostics = t.Result.Where(d => ruleIds.Contains(d.Id)).ToImmutableArray();
                        if (configuration.RunInfoLevelDiagnostics)
                        {
                            diagnostics = diagnostics.Where(d => d.Severity != DiagnosticSeverity.Info).ToImmutableArray();
                        }
                        LogDiagnostics(p.Project, diagnostics);

                        return t;
                    }).Unwrap()})
                .ToList();

            // And need to wait when all the analysis and printing tasks would be finished
            await Task.WhenAll(projectAnalysisTasks.Select(p => p.Task));

            // And only after now we can build the result
            var result =
                projectAnalysisTasks
                .Select(r => new ProjectAnalysisResult(r.Project, r.Task.Result.Where(d => ruleIds.Contains(d.Id)).ToImmutableArray())).ToList();

            return result;
        }
예제 #19
0
        public async Task Parse()
        {
            using (var workspace = MSBuildWorkspace.Create())
            {
                projects = new List <Project>();
                if (!isProjFilename)
                {
                    solution = await workspace.OpenSolutionAsync(filename);

                    foreach (var csProj in solution.Projects)
                    {
                        var proj = new Project(this, csProj);
                        projects.Add(proj);
                        await proj.Parse();
                    }
                }
                else
                {
                    var csProj = await workspace.OpenProjectAsync(filename);

                    solution = csProj.Solution;
                    var proj = new Project(this, csProj);
                    projects.Add(proj);
                    await proj.Parse();
                }
            }
        }
 public static Task<IEnumerable<INamedTypeSymbol>> FindDerivedInterfacesAsync(
     this INamedTypeSymbol type,
     Solution solution,
     CancellationToken cancellationToken)
 {
     return FindDerivedInterfacesAsync(type, solution, null, cancellationToken);
 }
            private async Task<Solution> RenameFields(Solution solution, DocumentId documentId, int count, CancellationToken cancellationToken)
            {
                Solution oldSolution = null;
                for (int i = 0; i < count; i++)
                {
                    oldSolution = solution;

                    var semanticModel = await solution.GetDocument(documentId).GetSemanticModelAsync(cancellationToken);
                    var root = await semanticModel.SyntaxTree.GetRootAsync(cancellationToken);
                    var declaration = root.GetAnnotatedNodes(s_markerAnnotation).ElementAt(i);
                    var fieldSymbol = (IFieldSymbol)semanticModel.GetDeclaredSymbol(declaration, cancellationToken);
                    var newName = GetNewFieldName(fieldSymbol);

                    // Can happen with pathologically bad field names like _
                    if (newName == fieldSymbol.Name)
                    {
                        continue;
                    }

                    solution = await Renamer.RenameSymbolAsync(solution, fieldSymbol, newName, solution.Workspace.Options, cancellationToken).ConfigureAwait(false);
                    solution = await CleanSolutionAsync(solution, oldSolution, cancellationToken);
                }

                return solution;
            }
        internal static bool TryGetReference(
            Solution solution, ProjectReference projectReference, Compilation finalOrDeclarationCompilation, VersionStamp version, out MetadataReference reference)
        {
            // if we have one from snapshot cache, use it. it will make sure same compilation will get same metadata reference always.
            MetadataOnlyReferenceSet referenceSet;
            if (s_snapshotCache.TryGetValue(finalOrDeclarationCompilation, out referenceSet))
            {
                reference = referenceSet.GetMetadataReference(finalOrDeclarationCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes);
                return true;
            }

            // okay, now use version based cache that can live multiple compilation as long as there is no semantic changes.

            // get one for the branch
            if (TryGetReferenceFromBranch(solution.BranchId, projectReference, finalOrDeclarationCompilation, version, out reference))
            {
                return true;
            }

            // see whether we can use primary branch one
            var primaryBranchId = solution.Workspace.PrimaryBranchId;
            if (solution.BranchId != primaryBranchId &&
                TryGetReferenceFromBranch(primaryBranchId, projectReference, finalOrDeclarationCompilation, version, out reference))
            {
                return true;
            }

            // noop, we don't have any
            reference = null;
            return false;
        }
예제 #23
0
 public PreviewEngine(
     string title,
     string helpString,
     string description,
     string topLevelItemName,
     Glyph topLevelGlyph,
     Solution newSolution,
     Solution oldSolution,
     IComponentModel componentModel,
     IVsImageService2 imageService,
     bool showCheckBoxes = true)
 {
     _topLevelName = topLevelItemName;
     _topLevelGlyph = topLevelGlyph;
     _title = title;
     _helpString = helpString;
     _description = description;
     _newSolution = newSolution.WithMergedLinkedFileChangesAsync(oldSolution, cancellationToken: CancellationToken.None).Result;
     _oldSolution = oldSolution;
     _diffSelector = componentModel.GetService<ITextDifferencingSelectorService>();
     _editorFactory = componentModel.GetService<IVsEditorAdaptersFactoryService>();
     _componentModel = componentModel;
     this.ShowCheckBoxes = showCheckBoxes;
     _imageService = imageService;
 }
예제 #24
0
        // TODO Refactor
        private IEnumerable<ClassCouplingMetrics> AnalyzeCoupling(Solution solution)
        {
            var documents = _documentWalker.GetAllDocumentsFromSolution(solution);
            foreach (var document in documents)
            {
                var typeDeclarations = _documentWalker.GetNodesFromDocument<TypeDeclarationSyntax>(document);
                var semanticModel = document.GetSemanticModelAsync().Result;

                foreach (var type in typeDeclarations)
                {
                    var classCouplingMetrics = new ClassCouplingMetrics(type.Identifier.Text);
                    var invocations = type.DescendantNodes().OfType<InvocationExpressionSyntax>();
                    foreach (var invocation in invocations)
                    {
                        classCouplingMetrics.TotalAmountCalls ++;
                        string nameSpace;
                        if (IsInternal(invocation, semanticModel, out nameSpace))
                        {
                            classCouplingMetrics.TotalInternCalls++;
                        }
                        else
                        {
                            classCouplingMetrics.TotalExternCalls++;
                            classCouplingMetrics.AddExternCall(nameSpace);
                        }
                    }
                    yield return classCouplingMetrics;
                }
            }
        }
예제 #25
0
        /// <summary>
        /// Initializes the P# program info.
        /// </summary>
        public static void Initialize()
        {
            ProgramInfo.CheckForCommandLineOptionErrors();

            // Create a new workspace.
            var workspace = MSBuildWorkspace.Create();

            try
            {
                // Populate the workspace with the user defined solution.
                ProgramInfo.Solution = (workspace as MSBuildWorkspace).OpenSolutionAsync(
                    @"" + Configuration.SolutionFilePath + "").Result;
            }
            catch (Exception ex)
            {
                Output.Print(ex.StackTrace);
                ErrorReporter.ReportAndExit("Please give a valid solution path.");
            }

            if (!Configuration.ProjectName.Equals(""))
            {
                // Find the project specified by the user.
                var project = ProgramInfo.GetProjectWithName(Configuration.ProjectName);
                if (project == null)
                {
                    ErrorReporter.ReportAndExit("Please give a valid project name.");
                }
            }

            ProgramInfo.HasInitialized = true;
        }
예제 #26
0
        public async Task<GraphBuilder> GetGraphAsync(Solution solution, IGraphContext context, CancellationToken cancellationToken)
        {
            var graphBuilder = await GraphBuilder.CreateForInputNodesAsync(solution, context.InputNodes, cancellationToken).ConfigureAwait(false);

            foreach (var node in context.InputNodes)
            {
                var namedType = graphBuilder.GetSymbol(node) as INamedTypeSymbol;
                if (namedType == null)
                {
                    continue;
                }

                if (namedType.TypeKind == TypeKind.Class)
                {
                    var derivedTypes = await namedType.FindDerivedClassesAsync(solution, cancellationToken).ConfigureAwait(false);
                    foreach (var derivedType in derivedTypes)
                    {
                        var symbolNode = await graphBuilder.AddNodeForSymbolAsync(derivedType, relatedNode: node).ConfigureAwait(false);
                        graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node);
                    }
                }
                else if (namedType.TypeKind == TypeKind.Interface)
                {
                    var derivedTypes = await namedType.FindDerivedInterfacesAsync(solution, cancellationToken).ConfigureAwait(false);
                    foreach (var derivedType in derivedTypes)
                    {
                        var symbolNode = await graphBuilder.AddNodeForSymbolAsync(derivedType, relatedNode: node).ConfigureAwait(false);
                        graphBuilder.AddLink(symbolNode, CodeLinkCategories.InheritsFrom, node);
                    }
                }
            }

            return graphBuilder;
        }
예제 #27
0
        public SolutionGenerator(
            string projectFilePath,
            string commandLineArguments,
            string outputAssemblyPath,
            string solutionSourceFolder,
            string solutionDestinationFolder,
            string serverPath,
            string networkShare)
        {
            this.ProjectFilePath = projectFilePath;
            string projectName = Path.GetFileNameWithoutExtension(projectFilePath);
            string language = projectFilePath.EndsWith(".vbproj", StringComparison.OrdinalIgnoreCase) ?
                LanguageNames.VisualBasic : LanguageNames.CSharp;
            this.SolutionSourceFolder = solutionSourceFolder;
            this.SolutionDestinationFolder = solutionDestinationFolder;
            this.ServerPath = serverPath;
            this.NetworkShare = networkShare;
            string projectSourceFolder = Path.GetDirectoryName(projectFilePath);

            this.solution = CreateSolution(
                commandLineArguments,
                projectName,
                language,
                projectSourceFolder,
                outputAssemblyPath);
        }
 public LinkedFileDiffMergingSession(Solution oldSolution, Solution newSolution, SolutionChanges solutionChanges, bool logSessionInfo)
 {
     _oldSolution = oldSolution;
     _newSolution = newSolution;
     _solutionChanges = solutionChanges;
     _logSessionInfo = logSessionInfo;
 }
		protected override Task<EvaluationResult> EvaluateImpl(SyntaxNode node, SemanticModel semanticModel, Solution solution)
		{
			//// TODO: For this to be correct, we need flow analysis to determine if a given method
			//// is actually invoked inside the current constructor. A method may be assigned to a
			//// delegate which can be called inside or outside the constructor. A method may also
			//// be called from within a lambda which is called inside or outside the constructor.
			//// Currently, FxCop does not produce a warning if a virtual method is called indirectly
			//// through a delegate or through a lambda.

			var constructor = (ConstructorDeclarationSyntax)node;
			var constructorSymbol = semanticModel.GetDeclaredSymbol(constructor);
			var containingType = constructorSymbol.ContainingType;

			if (
				constructor.Body.DescendantNodes()
				.Where(x => x.Kind() == SyntaxKind.InvocationExpression)
					.Any(x => CallVirtualMethod((InvocationExpressionSyntax)x, semanticModel, containingType)))
			{
				var result = new EvaluationResult
								 {
									 Snippet = node.ToFullString(),
									 LinesOfCodeAffected = GetLinesOfCode(node)
								 };
				return Task.FromResult(result);
			}

			return Task.FromResult<EvaluationResult>(null);
		}
        private async Task FindReferencesInServiceProcessAsync(
            SymbolAndProjectId symbolAndProjectId,
            Solution solution, 
            IStreamingFindReferencesProgress progress, 
            IImmutableSet<Document> documents, 
            CancellationToken cancellationToken)
        {
            var clientService = solution.Workspace.Services.GetService<IRemoteHostClientService>();
            var client = await clientService.GetRemoteHostClientAsync(cancellationToken).ConfigureAwait(false);

            if (client == null)
            {
                await DefaultSymbolFinderEngineService.FindReferencesInCurrentProcessAsync(
                    symbolAndProjectId, solution, progress, documents, cancellationToken).ConfigureAwait(false);
                return;
            }

            // Create a callback that we can pass to the server process to hear about the 
            // results as it finds them.  When we hear about results we'll forward them to
            // the 'progress' parameter which will then upate the UI.
            var serverCallback = new ServerCallback(solution, progress, cancellationToken);

            using (var session = await client.CreateCodeAnalysisServiceSessionAsync(
                solution, serverCallback, cancellationToken).ConfigureAwait(false))
            {
                await session.InvokeAsync(
                    WellKnownServiceHubServices.CodeAnalysisService_FindReferencesAsync,
                    SerializableSymbolAndProjectId.Dehydrate(symbolAndProjectId),
                    documents?.Select(SerializableDocumentId.Dehydrate).ToArray()).ConfigureAwait(false);
            }
        }
        private async Task FillReferencedProjectSetRecursivelyAsync(Solution solution, string projectName, ConcurrentDictionary <string, object> knownReferences)
        {
            var addedFirst = knownReferences.TryAdd(projectName, null);

            if (!addedFirst)
            {
                return;
            }

            var a = solution.Projects.ToArray();

            var project = solution
                          .Projects
                          .Single(proj => proj.Name == projectName);

            var tasks = project
                        .ProjectReferences
                        .Select(async(reference) =>
            {
                var refProject = solution
                                 .Projects
                                 .Single(proj => proj.Id.Id == reference.ProjectId.Id);

                await FillReferencedProjectSetRecursivelyAsync(solution, refProject.Name, knownReferences);
            });

            await Task.WhenAll(tasks);
        }
예제 #32
0
        private static async Task<Tuple<bool, Solution>> RenameOneSymbol(Solution solution, OptionSet renameOptions)
        {
            // Go through all project and documents, lookup classes and fields inside them. 
            // If any field needs renaming, perform rename operation
            var changes = from project in solution.Projects
                          from document in project.Documents
                          let root = document.GetSyntaxRootAsync().Result
                          let semantic = document.GetSemanticModelAsync().Result
                          from @class in root.DescendantNodes().OfType<ClassDeclarationSyntax>()
                          let classSymbol = semantic.GetDeclaredSymbol(@class)
                          from field in classSymbol.GetMembers().OfType<IFieldSymbol>().Where(x => !x.IsImplicitlyDeclared)
                          where field.Name.StartsWith("_")
                          let newName = field.Name.Substring(1)
                          select Renamer.RenameSymbolAsync(solution, field, newName, renameOptions);

            // Linq is lazy, so nothing has been done yet. Try to get first element (this will start rename) and if it exists, await it and return new solution
            var change = changes.FirstOrDefault();
            if (change != null)
            {
                return Tuple.Create(true, await change);
            }
            else
            {
                return Tuple.Create(false, solution);
            }
        }
        static void ListFileInfo(Microsoft.CodeAnalysis.Solution solution, string targetFile)
        {
            var document = solution.Projects.SelectMany(n => n.Documents.Where(m => m.Name == targetFile)).Single();

            var    documentSourceText = document.GetTextAsync().Result;
            string documentString     = documentSourceText.ToString();

            Console.WriteLine(documentString);
        }
예제 #34
0
        private async Task <IEnumerable <RoslynService> > GetServicesAsync(Solution solution)
        {
            var derivedClasses = await GetDerivedClassesAsync(solution, ReflectionNames.BASE_SERVICE_TYPE);

            return(derivedClasses.Select(dc => {
                var service = new RoslynService(dc);
                service.Fill();
                return service;
            }));
        }
예제 #35
0
        private async Task <IEnumerable <RoslynPageType> > GetPagesAsync(Solution solution)
        {
            var derivedClasses = await GetDerivedClassesAsync(solution, ReflectionNames.BASE_PAGE_TYPE);

            return(derivedClasses.Select(dc => {
                var page = new RoslynPageType(dc);
                page.Fill();
                return page;
            }));
        }
예제 #36
0
        private async Task <IEnumerable <RoslynComponentType> > GetComponentsAsync(Solution solution)
        {
            var derivedClasses = await GetDerivedClassesAsync(solution, ReflectionNames.BASE_COMPONENT_TYPE);

            return(derivedClasses.Select(dc => {
                var component = new RoslynComponentType(dc);
                component.Fill();
                return component;
            }));
        }
예제 #37
0
        private async Task <IEnumerable <INamedTypeSymbol> > GetDerivedClassesAsync(Solution solution, string baseClassName)
        {
            INamedTypeSymbol baseType = await GetTypeByNameAsync(solution, baseClassName);

            if (baseType != null)
            {
                return(await SymbolFinder
                       .FindDerivedClassesAsync(baseType, solution, solution.Projects.ToImmutableHashSet())
                       .ConfigureAwait(false));//.Where(dc => !dc.IsAbstract);
            }
            return(new List <INamedTypeSymbol>());
        }
예제 #38
0
        public override bool TryApplyChanges(Microsoft.CodeAnalysis.Solution newSolution)
        {
            // first make sure we can edit the document we will be updating (check them out from source control, etc)
            var changedDocs = newSolution.GetChanges(this.CurrentSolution).GetProjectChanges().SelectMany(pd => pd.GetChangedDocuments()).ToList();

            if (changedDocs.Count > 0)
            {
                this.EnsureEditableDocuments(changedDocs);
            }

            return(base.TryApplyChanges(newSolution));
        }
예제 #39
0
        private void ApplyChanges(Microsoft.CodeAnalysis.Document oldDocument, Microsoft.CodeAnalysis.Document newDocument)
        {
            oldDocument.ThrowOnNull(nameof(oldDocument));
            newDocument.ThrowOnNull(nameof(newDocument));

            Workspace workspace = oldDocument.Project?.Solution?.Workspace;

            Microsoft.CodeAnalysis.Solution newSolution = newDocument.Project?.Solution;

            if (workspace != null && newSolution != null)
            {
                workspace.TryApplyChanges(newSolution);
            }
        }
예제 #40
0
        // Almost there, I think, but not currently working.
        public static async Task <(bool OverallSuccess, EmitResult?TriggeringFailure)> CompileWithRosyln(string solutionUrl, string outputDir, CancellationToken cancel)
        {
            MSBuildWorkspace workspace = MSBuildWorkspace.Create();

            Microsoft.CodeAnalysis.Solution solution     = workspace.OpenSolutionAsync(solutionUrl).Result;
            ProjectDependencyGraph          projectGraph = solution.GetProjectDependencyGraph();

            foreach (ProjectId projectId in projectGraph.GetTopologicallySortedProjects())
            {
                Compilation?compilation = await solution.GetProject(projectId) !.GetCompilationAsync().ConfigureAwait(false);

                if (compilation == null || string.IsNullOrEmpty(compilation.AssemblyName))
                {
                    return(false, default);
예제 #41
0
        internal override bool TryApplyChanges(
            Microsoft.CodeAnalysis.Solution newSolution,
            IProgressTracker progressTracker)
        {
            if (_foregroundObject.IsValueCreated && !_foregroundObject.Value.IsForeground())
            {
                throw new InvalidOperationException(ServicesVSResources.VisualStudioWorkspace_TryApplyChanges_cannot_be_called_from_a_background_thread);
            }

            var projectChanges = newSolution.GetChanges(this.CurrentSolution).GetProjectChanges().ToList();
            var projectsToLoad = new HashSet <Guid>();

            foreach (var pc in projectChanges)
            {
                if (pc.GetAddedAdditionalDocuments().Any() ||
                    pc.GetAddedAnalyzerReferences().Any() ||
                    pc.GetAddedDocuments().Any() ||
                    pc.GetAddedMetadataReferences().Any() ||
                    pc.GetAddedProjectReferences().Any() ||
                    pc.GetRemovedAdditionalDocuments().Any() ||
                    pc.GetRemovedAnalyzerReferences().Any() ||
                    pc.GetRemovedDocuments().Any() ||
                    pc.GetRemovedMetadataReferences().Any() ||
                    pc.GetRemovedProjectReferences().Any())
                {
                    projectsToLoad.Add(GetHostProject(pc.ProjectId).Guid);
                }
            }

            if (projectsToLoad.Any())
            {
                var vsSolution4 = (IVsSolution4)DeferredState.ServiceProvider.GetService(typeof(SVsSolution));
                vsSolution4.EnsureProjectsAreLoaded(
                    (uint)projectsToLoad.Count,
                    projectsToLoad.ToArray(),
                    (uint)__VSBSLFLAGS.VSBSLFLAGS_None);
            }

            // first make sure we can edit the document we will be updating (check them out from source control, etc)
            var changedDocs = projectChanges.SelectMany(pd => pd.GetChangedDocuments()).ToList();

            if (changedDocs.Count > 0)
            {
                this.EnsureEditableDocuments(changedDocs);
            }

            return(base.TryApplyChanges(newSolution, progressTracker));
        }
예제 #42
0
파일: Form1.cs 프로젝트: VE-2016/VE-2016
        public async void CompileSolution()
        {
            var _ = typeof(Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOptions);

            string solutionFileName = "C:\\MSBuildProjects-beta\\VStudio.sln";


            VSSolutionLoader rw = new VSSolutionLoader();

            System.Windows.Forms.TreeView vv = rw.LoadProject(solutionFileName);

            VSSolution vs = vv.Tag as VSSolution;

            MessageBox.Show("VSolution loaded.." + vs.Name);

            comp = new Dictionary <string, Compilation>();

            named = new Dictionary <string, List <INamespaceOrTypeSymbol> >();

            workspace = null;

            ProjectDependencyGraph projectGraph = null;

            Microsoft.CodeAnalysis.Solution solution = null;
            workspace = MSBuildWorkspace.Create();
            solution  = await workspace.OpenSolutionAsync(solutionFileName);

            projectGraph = solution.GetProjectDependencyGraph();

            foreach (ProjectId projectId in projectGraph.GetTopologicallySortedProjects())
            {
                Stopwatch sw = Stopwatch.StartNew();

                Compilation projectCompilation = solution.GetProject(projectId).GetCompilationAsync().Result;

                sw.Stop();

                System.Diagnostics.Debug.WriteLine("Time taken compilation creation: {0}ms", sw.Elapsed.TotalMilliseconds);

                Microsoft.CodeAnalysis.Project project = solution.GetProject(projectId);

                comp.Add(project.FilePath, projectCompilation);

                // List<INamespaceOrTypeSymbol> ns = GetAllTypes(project.FilePath);

                // named.Add(project.FilePath, ns);
            }
        }
예제 #43
0
        ExtractMethodsFromSolution(
            string solutionPath)
        {
            Solution solution = BuildSolution(solutionPath);

            if (solution == null)
            {
                return(null);
            }
            Console.WriteLine("Solution was build");
            var res = new List <Tuple <string, MethodCommentInfo, List <ApiCall>, List <MethodParameter> > >();

            foreach (var project in solution.Projects)
            {
                foreach (var document in project.Documents)
                {
                    if (!File.Exists(document.FilePath))
                    {
                        Console.WriteLine("File doesn't exist: ");
                        Console.WriteLine(document.FilePath);
                        continue;
                    }
                    Console.WriteLine("Working with " + document.FilePath);

                    var rootNode        = document.GetSyntaxRootAsync().Result;
                    var methodCollector = new MethodsCollector();
                    methodCollector.Visit(rootNode);

                    var methodsAndComments = CommentExtractor.ExtractSummaryComments(methodCollector.MethodDecls);
                    var curMethods         = methodsAndComments.Keys.ToList();

                    var model = document.GetSemanticModelAsync().Result;
                    foreach (var method in curMethods)
                    {
                        var methodNameAndCalls = ExtractApiSequence(method, model);
                        if (methodNameAndCalls.Item2.Count == 0)
                        {
                            continue;
                        }
                        res.Add(new Tuple <string, MethodCommentInfo, List <ApiCall>, List <MethodParameter> >(
                                    methodNameAndCalls.Item1, methodsAndComments[method], methodNameAndCalls.Item2,
                                    methodNameAndCalls.Item3));
                    }
                }
            }
            return(res);
        }
예제 #44
0
        public static Document GetActiveDocument()
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            Solution solution      = Workspace.CurrentSolution;
            string   activeDocPath = GetActiveDteDocument()?.FullName;

            if (activeDocPath != null)
            {
                return(solution.Projects
                       .SelectMany(x => x.Documents)
                       .FirstOrDefault(x => x.SupportsSyntaxTree &&
                                       x.SupportsSemanticModel &&
                                       x.FilePath == activeDocPath));
            }
            return(null);
        }
        private void Setup()
        {
            _configuration    = ProjectData.Configuration.AnalyzeConfiguration;
            _solution         = ProjectData.Project.Solution;
            _analyzeDocuments = ProjectData.Project.Documents
                                .Where(o => _configuration.DocumentSelectionPredicate(o))
                                .ToImmutableHashSet();
            _analyzeProjects = new[] { ProjectData.Project }
            .ToImmutableHashSet();
            _searchOptions = AsyncCounterpartsSearchOptions.Default;
            var useTokens = _configuration.UseCancellationTokens | _configuration.ScanForMissingAsyncMembers != null;

            if (useTokens)
            {
                _searchOptions |= AsyncCounterpartsSearchOptions.HasCancellationToken;
            }
        }
예제 #46
0
        private async Task <INamedTypeSymbol> GetTypeByNameAsync(Solution solution, string className)
        {
            foreach (var project in solution.Projects)
            {
                foreach (var document in project.Documents)
                {
                    SemanticModel semantic = await document.GetSemanticModelAsync().ConfigureAwait(false);

                    var baseType = semantic.Compilation.GetSymbolsWithName(name => name == className, SymbolFilter.Type).FirstOrDefault() as INamedTypeSymbol;
                    if (baseType != null)
                    {
                        return(baseType);
                    }
                }
            }
            return(null);
        }
        public async Task <HashSet <string> > GetProjectsDirectlyReferencingAsync(string solutionFilePath, string[] rootProjectNames)
        {
            var workspace = MSBuildWorkspace.Create();

            Solution solution = await workspace.OpenSolutionAsync(solutionFilePath);

            var rootProjectIds = solution.Projects
                                 .Where(proj => rootProjectNames.Contains(proj.Name))
                                 .Select(proj => proj.Id.Id)
                                 .ToArray();

            var referencingProjects = solution
                                      .Projects
                                      .Where(proj => proj.ProjectReferences.Any(reference => rootProjectIds.Contains(reference.ProjectId.Id)))
                                      .Distinct()
                                      .Select(proj => proj.Name);

            return(new HashSet <string>(referencingProjects));
        }
        /// <summary>
        /// 現在選択している型を取得します。
        /// </summary>
        private async Task <INamedTypeSymbol> GetSelectedTypeSymbolAsync(Microsoft.CodeAnalysis.Solution solution)
        {
            var activeDoc = _dte.ActiveDocument;

            if (activeDoc == null)
            {
                return(null);
            }

            var docId = solution.GetDocumentIdsWithFilePath(activeDoc.FullName).FirstOrDefault();

            if (docId == null)
            {
                return(null);
            }

            var doc       = solution.GetDocument(docId);
            var selection = (TextSelection)activeDoc.Selection;
            var position  = (selection.ActivePoint.AbsoluteCharOffset - 1) + (selection.CurrentLine - 1);
            var symbol    = await SymbolFinder.FindSymbolAtPositionAsync(doc, position);

            return(FindTypeSymbol(symbol));
        }
예제 #49
0
        internal static MetadataReference GetOrBuildReference(
            Solution solution,
            ProjectReference projectReference,
            Compilation finalCompilation,
            VersionStamp version,
            CancellationToken cancellationToken)
        {
            solution.Workspace.LogTestMessage($"Looking to see if we already have a skeleton assembly for {projectReference.ProjectId} before we build one...");
            MetadataReference reference;

            if (TryGetReference(solution, projectReference, finalCompilation, version, out reference))
            {
                solution.Workspace.LogTestMessage($"A reference was found {projectReference.ProjectId} so we're skipping the build.");
                return(reference);
            }

            // okay, we don't have one. so create one now.

            // first, prepare image
            // * NOTE * image is cancellable, do not create it inside of conditional weak table.
            var service = solution.Workspace.Services.GetService <ITemporaryStorageService>();
            var image   = MetadataOnlyImage.Create(solution.Workspace, service, finalCompilation, cancellationToken);

            if (image.IsEmpty)
            {
                // unfortunately, we couldn't create one. do best effort
                if (TryGetReference(solution, projectReference, finalCompilation, VersionStamp.Default, out reference))
                {
                    solution.Workspace.LogTestMessage($"We failed to create metadata so we're using the one we just found from an earlier version.");

                    // we have one from previous compilation!!, it might be out-of-date big time, but better than nothing.
                    // re-use it
                    return(reference);
                }
            }

            // okay, proceed with whatever image we have

            // now, remove existing set
            var mapFromBranch = s_cache.GetValue(solution.BranchId, s_createReferenceSetMap);

            mapFromBranch.Remove(projectReference.ProjectId);

            // create new one
            var newReferenceSet = new MetadataOnlyReferenceSet(version, image);
            var referenceSet    = s_snapshotCache.GetValue(finalCompilation, _ => newReferenceSet);

            if (newReferenceSet != referenceSet)
            {
                // someone else has beaten us.
                // let image go eagerly. otherwise, finalizer in temporary storage will take care of it
                image.Cleanup();

                // return new reference
                return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes));
            }
            else
            {
                solution.Workspace.LogTestMessage($"Successfully stored the metadata generated for {projectReference.ProjectId}");
            }

            // record it to version based cache as well. snapshot cache always has a higher priority. we don't need to check returned set here
            // since snapshot based cache will take care of same compilation for us.
            mapFromBranch.GetValue(projectReference.ProjectId, _ => referenceSet);

            // return new reference
            return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes));
        }
        private async Task <TestGenerationContext> CollectTestGenerationContextAsync(
            ProjectItemSummary selectedFile,
            string targetProjectNamespace,
            TestFramework testFramework,
            MockFramework mockFramework,
            IBoilerplateSettings settings)
        {
            Microsoft.CodeAnalysis.Solution solution = CreateUnitTestBoilerplateCommandPackage.VisualStudioWorkspace.CurrentSolution;
            DocumentId documentId = solution.GetDocumentIdsWithFilePath(selectedFile.FilePath).FirstOrDefault();

            if (documentId == null)
            {
                throw new InvalidOperationException("Could not find document in solution with file path " + selectedFile.FilePath);
            }

            var document = solution.GetDocument(documentId);

            SyntaxNode root = await document.GetSyntaxRootAsync();

            SemanticModel semanticModel = await document.GetSemanticModelAsync();

            SyntaxNode firstClassLikeDeclaration = root.DescendantNodes().FirstOrDefault(node =>
            {
                var kind = node.Kind();
                return(kind == SyntaxKind.ClassDeclaration || kind == SyntaxKind.StructDeclaration || kind == (SyntaxKind)9063);                // record - Cannot update CodeAnalysis library because it's not found in VS 2019
            });

            if (firstClassLikeDeclaration == null)
            {
                throw new InvalidOperationException("Could not find class, struct or record declaration.");
            }

            if (firstClassLikeDeclaration.ChildTokens().Any(node => node.Kind() == SyntaxKind.AbstractKeyword))
            {
                throw new InvalidOperationException("Cannot unit test an abstract class.");
            }

            SyntaxToken classIdentifierToken = firstClassLikeDeclaration.ChildTokens().FirstOrDefault(n => n.Kind() == SyntaxKind.IdentifierToken);

            if (classIdentifierToken == default(SyntaxToken))
            {
                throw new InvalidOperationException("Could not find class identifier.");
            }

            object namespaceDeclarationSyntax = null;

            // 8842 is NamespaceDeclaration
            // 8845 is FileScopedNamespaceDeclaration
            // We would normally look for a node descended from BaseNamespaceDeclarationSyntax, but we don't have that type defined in the v1 Microsoft.CodeAnalysis DLL.
            // We can fix this once we are building against a higher version and can drop support for VS 2019.
            if (!TypeUtilities.TryGetParentSyntax(firstClassLikeDeclaration, (syntaxNode) => { return(syntaxNode.RawKind == 8842 || syntaxNode.RawKind == 8845); }, out namespaceDeclarationSyntax))
            {
                throw new InvalidOperationException("Could not find class namespace.");
            }

            // Find property injection types
            var injectableProperties = new List <InjectableProperty>();

            // We need to get the name via reflection since the DLL we are building against does not have the BaseNamespaceDeclarationSyntax or FileScopedNamespaceDeclarationSyntax types.
            string qualifiedNamespaceString = namespaceDeclarationSyntax.GetType().GetProperty("Name").GetValue(namespaceDeclarationSyntax, null).ToString();

            string           classFullName = qualifiedNamespaceString + "." + classIdentifierToken;
            INamedTypeSymbol classType     = semanticModel.Compilation.GetTypeByMetadataName(classFullName);

            foreach (ISymbol member in classType.GetBaseTypesAndThis().SelectMany(n => n.GetMembers()))
            {
                if (member.Kind == SymbolKind.Property)
                {
                    IPropertySymbol property = (IPropertySymbol)member;

                    foreach (AttributeData attribute in property.GetAttributes())
                    {
                        if (PropertyInjectionAttributeNames.Contains(attribute.AttributeClass.ToString()))
                        {
                            var injectableProperty = InjectableProperty.TryCreateInjectableProperty(property.Name, property.Type.ToString(), mockFramework);
                            if (injectableProperty != null)
                            {
                                injectableProperties.Add(injectableProperty);
                            }
                        }
                    }
                }
            }

            string className = classIdentifierToken.ToString();

            // Find constructor injection types
            List <InjectableType> constructorInjectionTypes = new List <InjectableType>();

            SyntaxNode constructorDeclaration = firstClassLikeDeclaration.ChildNodes().FirstOrDefault(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

            if (constructorDeclaration != null)
            {
                constructorInjectionTypes.AddRange(
                    GetParameterListNodes(constructorDeclaration)
                    .Select(node => InjectableType.TryCreateInjectableTypeFromParameterNode(node, semanticModel, mockFramework)));
            }

            // Find public method declarations
            IList <MethodDescriptor> methodDeclarations = new List <MethodDescriptor>();

            foreach (MethodDeclarationSyntax methodDeclaration in
                     firstClassLikeDeclaration.ChildNodes().Where(
                         n => n.Kind() == SyntaxKind.MethodDeclaration &&
                         ((MethodDeclarationSyntax)n).Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword))))
            {
                var parameterList  = GetParameterListNodes(methodDeclaration).ToList();
                var parameterTypes = GetArgumentDescriptors(parameterList, semanticModel, mockFramework);

                var attributeList = GetAttributeListNodes(methodDeclaration);

                var isAsync =
                    methodDeclaration.Modifiers.Any(m => m.IsKind(SyntaxKind.AsyncKeyword)) ||
                    DoesReturnTask(methodDeclaration);

                var hasReturnType = !DoesReturnNonGenericTask(methodDeclaration) && !DoesReturnVoid(methodDeclaration);

                string returnType = methodDeclaration.ReturnType.ToFullString();

                methodDeclarations.Add(new MethodDescriptor(methodDeclaration.Identifier.Text, parameterTypes, isAsync, hasReturnType, returnType, attributeList));
            }

            string unitTestNamespace;

            string relativePath = this.GetRelativePath(selectedFile);

            if (string.IsNullOrEmpty(relativePath))
            {
                unitTestNamespace = targetProjectNamespace;
            }
            else
            {
                List <string> defaultNamespaceParts  = targetProjectNamespace.Split('.').ToList();
                List <string> unitTestNamespaceParts = new List <string>(defaultNamespaceParts);
                unitTestNamespaceParts.AddRange(relativePath.Split('\\'));

                unitTestNamespace = string.Join(".", unitTestNamespaceParts);
            }

            List <InjectableType> injectedTypes = new List <InjectableType>(injectableProperties);

            injectedTypes.AddRange(constructorInjectionTypes.Where(t => t != null));

            GenerateMockNames(injectedTypes);

            return(new TestGenerationContext(
                       mockFramework,
                       testFramework,
                       document,
                       settings,
                       unitTestNamespace,
                       className,
                       qualifiedNamespaceString,
                       injectableProperties,
                       constructorInjectionTypes,
                       injectedTypes,
                       methodDeclarations));
        }
예제 #51
0
        static async Task <IEnumerable <ISymbol> > FindInterfaceImplementaitonsAsync(INamedTypeSymbol type, Microsoft.CodeAnalysis.Solution currentSolution, CancellationToken token = default(CancellationToken))
        {
            var result = new List <ISymbol> ();

            foreach (var project in currentSolution.Projects)
            {
                var comp = await project.GetCompilationAsync(token).ConfigureAwait(false);

                foreach (var i in comp.GetAllTypesInMainAssembly(token).Where(t => t.TypeKind == TypeKind.Interface))
                {
                    if (i.AllInterfaces.Any(t => t.InheritsFromOrImplementsOrEqualsIgnoringConstruction(type)))
                    {
                        result.Add(i);
                    }
                }
            }

            return(result);
        }
예제 #52
0
        private void InitializeMutationProjects(UnimaFileConfig fileConfig, UnimaConfig config, Microsoft.CodeAnalysis.Solution solution)
        {
            if (fileConfig.IgnoredProjects == null)
            {
                fileConfig.IgnoredProjects = new List <string>();
            }

            LogTo.Info("Setting up mutation projects.");
            foreach (var solutionProject in solution.Projects)
            {
                if (IsIgnored(solutionProject.Name, fileConfig.IgnoredProjects) || IsTestProject(solutionProject.Name, fileConfig.TestProjects))
                {
                    continue;
                }

                LogTo.Info($"Grabbing output info for {solutionProject.Name}.");

                config.MutationProjects.Add(new SolutionProjectInfo(solutionProject.Name, UpdateOutputPathWithBuildConfiguration(solutionProject.OutputFilePath, config.BuildConfiguration)));
            }
        }
 public static Solution OpenSolution(MSBuildWorkspace workspace, string solutionLocation = "")
 {
     Microsoft.CodeAnalysis.Solution solution = workspace.OpenSolutionAsync(solutionLocation).Result;
     Console.WriteLine(String.Format("\nOpening solution: {0}\n", solutionLocation));
     return(solution);
 }
예제 #54
0
        private void SynchronizeNamespaces(List <Microsoft.CodeAnalysis.Document> documents, Microsoft.CodeAnalysis.Solution solution)
        {
            var solutionProjects = solution.Projects.Where(p => p.SupportsCompilation);

            var usingDirectiveChangelogs = new Dictionary <string, Dictionary <string, string> >();

            var projectReferences = new Dictionary <string, List <string> >();

            // 修复文件的命名空间
            for (var documentIndex = 0; documentIndex < documents.Count; documentIndex++)
            {
                var document         = documents[documentIndex];
                var project          = document.Project;
                var projectNamespace = string.IsNullOrEmpty(project.DefaultNamespace) ? project.Name : project.DefaultNamespace;
                var projectDir       = Path.GetDirectoryName(project.FilePath);

                if (document.TryGetSyntaxRoot(out var syntaxRoot) && syntaxRoot is CompilationUnitSyntax compilationUnitSyntax)
                {
                    var memberDeclarationSyntaxNodes = compilationUnitSyntax.Members.ToArray();
                    var documentFixed = false;
                    var documentDir   = Path.GetDirectoryName(document.FilePath);
                    for (var i = 0; i < memberDeclarationSyntaxNodes.Length; i++)
                    {
                        if (!(memberDeclarationSyntaxNodes[i] is NamespaceDeclarationSyntax namespaceDeclarationSyntaxNode))
                        {
                            continue;
                        }

                        var nameSpace = namespaceDeclarationSyntaxNode.Name.ToString();

                        var fixedNameSpace = projectNamespace;

                        if (documentDir.StartsWith(projectDir) && documentDir.Length > projectDir.Length)
                        {
                            var relativePath = documentDir.Substring(projectDir.Length);
                            fixedNameSpace = projectNamespace + relativePath.Replace(Path.DirectorySeparatorChar, '.').Replace(Path.AltDirectorySeparatorChar, '.');
                        }

                        if (nameSpace.Equals(fixedNameSpace))
                        {
                            continue;
                        }

                        var identifierNameSyntaxNodes = fixedNameSpace.Split('.').Where(n => !string.IsNullOrEmpty(n))
                                                        .Select(n => SyntaxFactory.IdentifierName(n)).ToArray();

                        if (identifierNameSyntaxNodes.Length <= 0)
                        {
                            continue;
                        }

                        NameSyntax nameSyntaxNode = identifierNameSyntaxNodes[0];

                        for (var ii = 1; ii < identifierNameSyntaxNodes.Length; ii++)
                        {
                            nameSyntaxNode = SyntaxFactory.QualifiedName(nameSyntaxNode, identifierNameSyntaxNodes[ii]);
                        }

                        if (!projectReferences.TryGetValue(project.FilePath, out var affectedProjects))
                        {
                            affectedProjects = solutionProjects.Where(p => p.AllProjectReferences.Any(r => r.ProjectId.Equals(project.Id))).Select(p => p.FilePath).ToList();
                            affectedProjects.Add(project.FilePath);
                            projectReferences.Add(project.FilePath, affectedProjects);
                        }


                        foreach (var affectedProject in affectedProjects)
                        {
                            if (!usingDirectiveChangelogs.TryGetValue(affectedProject, out var transformedNamespaces))
                            {
                                transformedNamespaces = new Dictionary <string, string>();
                                usingDirectiveChangelogs.Add(affectedProject, transformedNamespaces);
                            }
                            transformedNamespaces[nameSpace] = nameSyntaxNode.ToString();
                        }

                        nameSyntaxNode = nameSyntaxNode.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);

                        memberDeclarationSyntaxNodes[i] = namespaceDeclarationSyntaxNode.WithName(nameSyntaxNode);

                        documentFixed = true;
                    }

                    if (documentFixed)
                    {
                        documents[documentIndex] = document
                                                   .WithSyntaxRoot(
                            compilationUnitSyntax.WithMembers(
                                new SyntaxList <MemberDeclarationSyntax>(memberDeclarationSyntaxNodes)));
                    }
                }
            }


            var solutionDocuments = solutionProjects.Select(project => project.Documents.ToList()).DimensionReduction().ToList();

            // 修复解决方案中文件的命名空间引用
            for (var documentIndex = 0; documentIndex < solutionDocuments.Count; documentIndex++)
            {
                var document = solutionDocuments[documentIndex];
                if (!usingDirectiveChangelogs.TryGetValue(document.Project.FilePath, out var transformedNamespaces))
                {
                    continue;
                }
                if (document.TryGetSyntaxRoot(out var syntaxRoot) && syntaxRoot is CompilationUnitSyntax compilationUnitSyntax)
                {
                    var usingDirectiveSyntaxNodes = compilationUnitSyntax.Usings.ToArray();
                    var documentFixed             = false;
                    var documentDir = Path.GetDirectoryName(document.FilePath);
                    for (var i = 0; i < usingDirectiveSyntaxNodes.Length; i++)
                    {
                        var usingDirectiveSyntaxNode = usingDirectiveSyntaxNodes[i];
                        var key = usingDirectiveSyntaxNode.Name.ToString();
                        if (transformedNamespaces.ContainsKey(key))
                        {
                            usingDirectiveSyntaxNodes[i] = usingDirectiveSyntaxNode.WithName(SyntaxFactory.IdentifierName(transformedNamespaces[key]));
                            documentFixed = true;
                        }
                    }
                    if (documentFixed)
                    {
                        solutionDocuments[documentIndex] = document
                                                           .WithSyntaxRoot(
                            compilationUnitSyntax.WithUsings(
                                new SyntaxList <UsingDirectiveSyntax>(usingDirectiveSyntaxNodes)));
                    }
                }
            }
        }
        private async Task <string> GenerateUnitTestContentsFromFileAsync(string inputFilePath)
        {
            Microsoft.CodeAnalysis.Solution solution = CreateUnitTestBoilerplateCommandPackage.VisualStudioWorkspace.CurrentSolution;
            DocumentId documentId = solution.GetDocumentIdsWithFilePath(inputFilePath).FirstOrDefault();

            if (documentId == null)
            {
                this.HandleError("Could not find document in solution with file path " + inputFilePath);
            }

            var document = solution.GetDocument(documentId);

            SyntaxNode root = await document.GetSyntaxRootAsync();

            SemanticModel semanticModel = await document.GetSemanticModelAsync();

            SyntaxNode firstClassDeclaration = root.DescendantNodes().FirstOrDefault(node => node.Kind() == SyntaxKind.ClassDeclaration);

            if (firstClassDeclaration == null)
            {
                this.HandleError("Could not find class declaration.");
            }

            if (firstClassDeclaration.ChildTokens().Any(node => node.Kind() == SyntaxKind.AbstractKeyword))
            {
                this.HandleError("Cannot unit test an abstract class.");
            }

            SyntaxToken classIdentifierToken = firstClassDeclaration.ChildTokens().FirstOrDefault(n => n.Kind() == SyntaxKind.IdentifierToken);

            if (classIdentifierToken == null)
            {
                this.HandleError("Could not find class identifier.");
            }

            NamespaceDeclarationSyntax namespaceDeclarationSyntax = null;

            if (!Utilities.TryGetParentSyntax(firstClassDeclaration, out namespaceDeclarationSyntax))
            {
                this.HandleError("Could not find class namespace.");
            }

            // Find property injection types
            var injectableProperties = new List <InjectableProperty>();

            string           classFullName = namespaceDeclarationSyntax.Name + "." + classIdentifierToken;
            INamedTypeSymbol classType     = semanticModel.Compilation.GetTypeByMetadataName(classFullName);

            foreach (ISymbol member in classType.GetBaseTypesAndThis().SelectMany(n => n.GetMembers()))
            {
                if (member.Kind == SymbolKind.Property)
                {
                    IPropertySymbol property = (IPropertySymbol)member;

                    foreach (AttributeData attribute in property.GetAttributes())
                    {
                        if (attribute.AttributeClass.ToString() == "Microsoft.Practices.Unity.DependencyAttribute")
                        {
                            injectableProperties.Add(new InjectableProperty(property.Name, property.Type.Name, property.Type.ContainingNamespace.ToString()));
                        }
                    }
                }
            }

            this.className = classIdentifierToken.ToString();

            // Find constructor injection types
            var        constructorInjectionTypes = new List <InjectableType>();
            SyntaxNode constructorDeclaration    = firstClassDeclaration.ChildNodes().FirstOrDefault(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

            if (constructorDeclaration != null)
            {
                SyntaxNode parameterListNode = constructorDeclaration.ChildNodes().First(n => n.Kind() == SyntaxKind.ParameterList);
                var        parameterNodes    = parameterListNode.ChildNodes().Where(n => n.Kind() == SyntaxKind.Parameter);

                foreach (SyntaxNode node in parameterNodes)
                {
                    SyntaxNode identifierNode = node.ChildNodes().First(n => n.Kind() == SyntaxKind.IdentifierName);
                    SymbolInfo symbolInfo     = semanticModel.GetSymbolInfo(identifierNode);

                    constructorInjectionTypes.Add(
                        new InjectableType(
                            symbolInfo.Symbol.Name,
                            symbolInfo.Symbol.ContainingNamespace.ToString()));
                }
            }

            string unitTestNamespace;
            string defaultNamespace = this.SelectedProject.Project.Properties.Item("DefaultNamespace").Value as string;

            if (string.IsNullOrEmpty(this.relativePath))
            {
                unitTestNamespace = defaultNamespace;
            }
            else
            {
                List <string> defaultNamespaceParts  = defaultNamespace.Split('.').ToList();
                List <string> unitTestNamespaceParts = new List <string>(defaultNamespaceParts);
                unitTestNamespaceParts.AddRange(this.relativePath.Split('\\'));

                unitTestNamespace = string.Join(".", unitTestNamespaceParts);
            }

            return(this.GenerateUnitTestContents(
                       unitTestNamespace,
                       this.className,
                       namespaceDeclarationSyntax.Name.ToString(),
                       injectableProperties,
                       constructorInjectionTypes));
        }
        private async Task <TestGenerationContext> CollectTestGenerationContextAsync(
            ProjectItemSummary selectedFile,
            string targetProjectNamespace,
            TestFramework testFramework,
            MockFramework mockFramework)
        {
            Microsoft.CodeAnalysis.Solution solution = CreateUnitTestBoilerplateCommandPackage.VisualStudioWorkspace.CurrentSolution;
            DocumentId documentId = solution.GetDocumentIdsWithFilePath(selectedFile.FilePath).FirstOrDefault();

            if (documentId == null)
            {
                throw new InvalidOperationException("Could not find document in solution with file path " + selectedFile.FilePath);
            }

            var document = solution.GetDocument(documentId);

            SyntaxNode root = await document.GetSyntaxRootAsync();

            SemanticModel semanticModel = await document.GetSemanticModelAsync();

            SyntaxNode firstClassDeclaration = root.DescendantNodes().FirstOrDefault(node => node.Kind() == SyntaxKind.ClassDeclaration);

            if (firstClassDeclaration == null)
            {
                throw new InvalidOperationException("Could not find class declaration.");
            }

            if (firstClassDeclaration.ChildTokens().Any(node => node.Kind() == SyntaxKind.AbstractKeyword))
            {
                throw new InvalidOperationException("Cannot unit test an abstract class.");
            }

            SyntaxToken classIdentifierToken = firstClassDeclaration.ChildTokens().FirstOrDefault(n => n.Kind() == SyntaxKind.IdentifierToken);

            if (classIdentifierToken == default(SyntaxToken))
            {
                throw new InvalidOperationException("Could not find class identifier.");
            }

            NamespaceDeclarationSyntax namespaceDeclarationSyntax = null;

            if (!TypeUtilities.TryGetParentSyntax(firstClassDeclaration, out namespaceDeclarationSyntax))
            {
                throw new InvalidOperationException("Could not find class namespace.");
            }

            // Find property injection types
            var injectableProperties = new List <InjectableProperty>();

            string           classFullName = namespaceDeclarationSyntax.Name + "." + classIdentifierToken;
            INamedTypeSymbol classType     = semanticModel.Compilation.GetTypeByMetadataName(classFullName);

            foreach (ISymbol member in classType.GetBaseTypesAndThis().SelectMany(n => n.GetMembers()))
            {
                if (member.Kind == SymbolKind.Property)
                {
                    IPropertySymbol property = (IPropertySymbol)member;

                    foreach (AttributeData attribute in property.GetAttributes())
                    {
                        if (PropertyInjectionAttributeNames.Contains(attribute.AttributeClass.ToString()))
                        {
                            var injectableProperty = InjectableProperty.TryCreateInjectableProperty(property.Name, property.Type.ToString(), mockFramework);
                            if (injectableProperty != null)
                            {
                                injectableProperties.Add(injectableProperty);
                            }
                        }
                    }
                }
            }

            string className = classIdentifierToken.ToString();

            // Find constructor injection types
            List <InjectableType> constructorInjectionTypes = new List <InjectableType>();

            SyntaxNode constructorDeclaration = firstClassDeclaration.ChildNodes().FirstOrDefault(n => n.Kind() == SyntaxKind.ConstructorDeclaration);

            if (constructorDeclaration != null)
            {
                constructorInjectionTypes.AddRange(
                    GetParameterListNodes(constructorDeclaration)
                    .Select(node => InjectableType.TryCreateInjectableTypeFromParameterNode(node, semanticModel, mockFramework)));
            }

            // Find public method declarations
            IList <MethodDescriptor> methodDeclarations = new List <MethodDescriptor>();

            foreach (MethodDeclarationSyntax methodDeclaration in
                     firstClassDeclaration.ChildNodes().Where(
                         n => n.Kind() == SyntaxKind.MethodDeclaration &&
                         ((MethodDeclarationSyntax)n).Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword))))
            {
                var parameterList = GetParameterListNodes(methodDeclaration).ToList();

                var parameterTypes = GetArgumentDescriptors(parameterList, semanticModel, mockFramework);

                var isAsync =
                    methodDeclaration.Modifiers.Any(m => m.IsKind(SyntaxKind.AsyncKeyword)) ||
                    DoesReturnTask(methodDeclaration);

                var hasReturnType = !DoesReturnNonGenericTask(methodDeclaration) && !DoesReturnVoid(methodDeclaration);

                methodDeclarations.Add(new MethodDescriptor(methodDeclaration.Identifier.Text, parameterTypes, isAsync, hasReturnType));
            }

            string unitTestNamespace;

            string relativePath = this.GetRelativePath(selectedFile);

            if (string.IsNullOrEmpty(relativePath))
            {
                unitTestNamespace = targetProjectNamespace;
            }
            else
            {
                List <string> defaultNamespaceParts  = targetProjectNamespace.Split('.').ToList();
                List <string> unitTestNamespaceParts = new List <string>(defaultNamespaceParts);
                unitTestNamespaceParts.AddRange(relativePath.Split('\\'));

                unitTestNamespace = string.Join(".", unitTestNamespaceParts);
            }

            List <InjectableType> injectedTypes = new List <InjectableType>(injectableProperties);

            injectedTypes.AddRange(constructorInjectionTypes.Where(t => t != null));

            GenerateMockNames(injectedTypes);

            return(new TestGenerationContext(
                       mockFramework,
                       testFramework,
                       document,
                       unitTestNamespace,
                       className,
                       namespaceDeclarationSyntax.Name.ToString(),
                       injectableProperties,
                       constructorInjectionTypes,
                       injectedTypes,
                       methodDeclarations));
        }
        public override async Task RenameAsync(IProjectTreeActionHandlerContext context, IProjectTree node, string value)
        {
            Requires.NotNull(context, nameof(Context));
            Requires.NotNull(node, nameof(node));
            Requires.NotNullOrEmpty(value, nameof(value));

            string?oldFilePath          = node.FilePath;
            string oldName              = Path.GetFileNameWithoutExtension(oldFilePath);
            string newFileWithExtension = value;

            CodeAnalysis.Project?project = GetCurrentProject();

            // Rename the file
            await CPSRenameAsync(context, node, value);

            if (await IsAutomationFunctionAsync() || node.IsFolder || _vsOnlineServices.ConnectedToVSOnline ||
                FileChangedExtension(oldFilePath, newFileWithExtension))
            {
                // Do not display rename Prompt
                return;
            }

            if (project is null)
            {
                return;
            }

            string newName = Path.GetFileNameWithoutExtension(newFileWithExtension);

            if (!await CanRenameTypeAsync(project, oldName, newName))
            {
                return;
            }

            (bool result, Renamer.RenameDocumentActionSet? documentRenameResult) = await GetRenameSymbolsActionsAsync(project, oldFilePath, newFileWithExtension);

            if (!result || documentRenameResult == null)
            {
                return;
            }

            // Ask if the user wants to rename the symbol
            bool userWantsToRenameSymbol = await CheckUserConfirmationAsync(oldName);

            if (!userWantsToRenameSymbol)
            {
                return;
            }

            _threadingService.RunAndForget(async() =>
            {
                Solution currentSolution = await PublishLatestSolutionAsync();

                string renameOperationName = string.Format(CultureInfo.CurrentCulture, VSResources.Renaming_Type_from_0_to_1, oldName, value);
                WaitIndicatorResult <Solution> indicatorResult = _waitService.Run(
                    title: VSResources.Renaming_Type,
                    message: renameOperationName,
                    allowCancel: true,
                    token => documentRenameResult.UpdateSolutionAsync(currentSolution, token));

                // Do not warn the user if the rename was cancelled by the user
                if (indicatorResult.IsCancelled)
                {
                    return;
                }

                await _projectVsServices.ThreadingService.SwitchToUIThread();
                if (_roslynServices.ApplyChangesToSolution(currentSolution.Workspace, indicatorResult.Result))
                {
                    return;
                }

                string failureMessage = string.Format(CultureInfo.CurrentCulture, VSResources.RenameSymbolFailed, oldName);
                _userNotificationServices.ShowWarning(failureMessage);
            }, _unconfiguredProject);
        }
예제 #58
0
        private void InitializeTestProjects(UnimaFileConfig fileConfig, UnimaConfig config, Microsoft.CodeAnalysis.Solution solution)
        {
            if (fileConfig.TestProjects == null || !fileConfig.TestProjects.Any())
            {
                throw new ProjectSetUpException("Test project list is null or empty");
            }

            LogTo.Info("Setting up test projects.");
            foreach (var testProjectName in fileConfig.TestProjects)
            {
                var testProjects = solution.Projects.Where(p => Regex.IsMatch(p.Name, FormattedProjectName(testProjectName), RegexOptions.IgnoreCase));

                if (!testProjects.Any())
                {
                    throw new ProjectSetUpException($"Could not find any project with the name {testProjectName} in the solution.");
                }

                foreach (var testProject in testProjects)
                {
                    LogTo.Info($"Found the test project {testProject.Name}. Grabbing output info.");

                    if (IsIgnored(testProject.Name, fileConfig.IgnoredProjects))
                    {
                        LogTo.Info("But it was ignored. So skipping");
                        continue;
                    }

                    var testProjectOutput = UpdateOutputPathWithBuildConfiguration(testProject.OutputFilePath, config.BuildConfiguration);
                    LogTo.Info($"Wanted build configuration is \"{config.BuildConfiguration}\". Setting test project output to \"{testProjectOutput}\"");
                    config.TestProjects.Add(new TestProject {
                        Project = new SolutionProjectInfo(testProject.Name, testProjectOutput), TestRunner = GetTestRunner(testProject, fileConfig.TestRunner)
                    });
                }
            }
        }
예제 #59
0
        private static async Task <GenerationResult> GenerateAsync(bool withRegeneration, IUnitTestGeneratorOptions options, Solution solution, GenerationItem generationItem, SemanticModel semanticModel)
        {
            GenerationResult result;

            if (File.Exists(generationItem.TargetFileName))
            {
                var documentIds = solution.GetDocumentIdsWithFilePath(generationItem.TargetFileName);
                if (documentIds.FirstOrDefault() is DocumentId targetDocumentId)
                {
                    var targetDocument = solution.GetDocument(targetDocumentId);

                    var targetSemanticModel = await targetDocument.GetSemanticModelAsync().ConfigureAwait(true);

                    result = await CoreGenerator.Generate(semanticModel, generationItem.SourceSymbol, targetSemanticModel, withRegeneration, options, generationItem.NamespaceTransform).ConfigureAwait(true);
                }
                else
                {
                    result = await CoreGenerator.Generate(semanticModel, generationItem.SourceSymbol, null, withRegeneration, options, generationItem.NamespaceTransform).ConfigureAwait(true);
                }
            }
            else
            {
                result = await CoreGenerator.Generate(semanticModel, generationItem.SourceSymbol, null, withRegeneration, options, generationItem.NamespaceTransform).ConfigureAwait(true);
            }

            return(result);
        }
예제 #60
0
 private void GetCurrentSolution(out Solution solution)
 {
     solution = GetWorkspace().CurrentSolution;
 }