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; }
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); } }
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(); }
public override void DisplayReferencedSymbols(Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols) { foreach (var presenter in _referencedSymbolsPresenters) { presenter.Value.DisplayResult(solution, referencedSymbols); } }
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; } }
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; }
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; } }
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; }
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; }
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; }
// 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; } } }
/// <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; }
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; }
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); }
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); }
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; })); }
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; })); }
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; })); }
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>()); }
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)); }
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); } }
// 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);
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)); }
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); } }
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); }
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; } }
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)); }
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)); }
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); }
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); }
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); }
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) }); } } }
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); }
private void GetCurrentSolution(out Solution solution) { solution = GetWorkspace().CurrentSolution; }