public void ApiAnalysis_Returns_Compatible_When_ApiVersion_Matches_A_CompatibleVersion() { var sourceFileToInvocations = new Dictionary <string, List <CodeEntityDetails> > { { "file1", new UstList <CodeEntityDetails> { new CodeEntityDetails { Name = "JsonConvert.SerializeObject", OriginalDefinition = "Newtonsoft.Json.JsonConvert.SerializeObject(object)", Namespace = "Newtonsoft.Json", Package = new PackageVersionPair { PackageId = "Newtonsoft.Json", Version = "10.2.0" }, TextSpan = new TextSpan(), CodeEntityType = CodeEntityType.Method } } } }; var package = new PackageVersionPair { PackageId = "Newtonsoft.Json", Version = "10.2.0" }; var packageTask = new TaskCompletionSource <PackageDetails>(); packageTask.SetResult(_packageDetails); _packageResults = new Dictionary <PackageVersionPair, Task <PackageDetails> > { { package, packageTask.Task } }; var results = CodeEntityModelToCodeEntities.AnalyzeResults( sourceFileToInvocations, _packageResults, _recommendationResults, new Dictionary <string, List <RecommendedAction> >()); var apiAnalysisResults = results.First().ApiAnalysisResults; Assert.AreEqual("10.2.0", apiAnalysisResults.First().CodeEntityDetails.Package.Version); Assert.AreEqual(Compatibility.COMPATIBLE, apiAnalysisResults.First().CompatibilityResults.GetValueOrDefault(DEFAULT_TARGET).Compatibility); Assert.AreEqual("12.0.3", apiAnalysisResults[0].Recommendations.RecommendedActions.First().Description); }
public void BadVersion() { var sourceFileToInvocations = new Dictionary <string, UstList <UstNode> > { { "file1", new UstList <UstNode> { new MockInvocationExpressionModel("definition", "namespace.namespace2.namespace3", "namespace2") } } }; var project = new AnalyzerResult { ProjectResult = new ProjectWorkspace("") { ExternalReferences = new ExternalReferences { NugetReferences = new List <ExternalReference> { new ExternalReference { AssemblyLocation = "namespace.dll", Identity = "namespace", Version = "*" }, new ExternalReference { AssemblyLocation = "namespace2.dll", Identity = "namespace.namespace2", Version = "NOT_SEMVER" } } } }, OutputJsonFilePath = null, ProjectBuildResult = null }; var result = CodeEntityModelToCodeEntities.Convert( sourceFileToInvocations, project); Assert.AreEqual(1, result["file1"].Count); Assert.AreEqual("namespace.namespace2", result["file1"][0].Package.PackageId); Assert.AreEqual("NOT_SEMVER", result["file1"][0].Package.Version); }
public void MultipleNuget() { var sourceFileToInvocations = new Dictionary <string, UstList <UstNode> > { { "file1", new UstList <UstNode> { new MockInvocationExpressionModel("Newtonsoft.Json.JsonConvert.SerializeObject(object)", "namespace.namespace2.namespace3", "test") } } }; var project = new AnalyzerResult { ProjectResult = new ProjectWorkspace("") { ExternalReferences = new ExternalReferences { NugetReferences = new List <ExternalReference> { new ExternalReference { AssemblyLocation = "test.dll", Identity = "namespace", Version = "1.2" }, new ExternalReference { AssemblyLocation = "test2.dll", Identity = "namespace.namespace2", Version = "1.2" } } } }, OutputJsonFilePath = null, ProjectBuildResult = null }; var result = CodeEntityModelToCodeEntities.Convert( sourceFileToInvocations, project); Assert.AreEqual(1, result["file1"].Count); Assert.AreEqual("1.2.0", result["file1"][0].Package.Version); }
public void NoPackageResultsTest() { var sourceFileToInvocations = new Dictionary <string, List <CodeEntityDetails> > { { "file1", new List <CodeEntityDetails> { _codeEntityDetails } } }; var result = CodeEntityModelToCodeEntities.AnalyzeResults( sourceFileToInvocations, new Dictionary <PackageVersionPair, Task <PackageDetails> >(), _recommendationResults, new Dictionary <string, List <RecommendedAction> >()); Assert.AreEqual(1, result.First().ApiAnalysisResults.Count); Assert.AreEqual("11.0.1", result.First().ApiAnalysisResults.First().CodeEntityDetails.Package.Version); Assert.AreEqual(Compatibility.UNKNOWN, result.First().ApiAnalysisResults.First().CompatibilityResults.GetValueOrDefault(DEFAULT_TARGET).Compatibility); Assert.IsNull(result[0].ApiAnalysisResults[0].Recommendations.RecommendedActions.First().Description); }
public void NormalAnalyzeCaseTest() { var sourceFileToInvocations = new Dictionary <string, List <CodeEntityDetails> > { { "file1", new UstList <CodeEntityDetails> { _codeEntityDetails } } }; var result = CodeEntityModelToCodeEntities.AnalyzeResults( sourceFileToInvocations, packageResults, recommendationResults, new Dictionary <string, List <RecommendedAction> >()); Assert.AreEqual(1, result.First().ApiAnalysisResults.Count); Assert.AreEqual("11.0.1", result.First().ApiAnalysisResults.First().CodeEntityDetails.Package.Version); Assert.AreEqual(Compatibility.COMPATIBLE, result.First().ApiAnalysisResults.First().CompatibilityResults.GetValueOrDefault(DEFAULT_TARGET).Compatibility); Assert.AreEqual("12.0.3", result[0].ApiAnalysisResults[0].Recommendations.RecommendedActions.First().Description); }
public async Task <List <SourceFileAnalysisResult> > AnalyzeFileIncremental(string filePath, string fileContent, string projectFile, string solutionFilePath, List <string> preportReferences , List <string> currentReferences, RootNodes projectRules, ExternalReferences externalReferences, bool actionsOnly = false, bool compatibleOnly = false, string targetFramework = DEFAULT_TARGET) { try { List <SourceFileAnalysisResult> sourceFileAnalysisResults = new List <SourceFileAnalysisResult>(); var fileAnalysis = await AnalyzeProjectFiles(projectFile, fileContent, filePath, preportReferences, currentReferences); var fileActions = AnalyzeFileActionsIncremental(projectFile, projectRules, targetFramework, solutionFilePath, filePath, fileAnalysis); var sourceFileResult = fileAnalysis.RootNodes.FirstOrDefault(); Dictionary <string, List <CodeEntityDetails> > sourceFileToCodeEntityDetails = new Dictionary <string, List <CodeEntityDetails> >(); Dictionary <string, Task <RecommendationDetails> > recommendationResults = new Dictionary <string, Task <RecommendationDetails> >(); Dictionary <PackageVersionPair, Task <PackageDetails> > packageResults = new Dictionary <PackageVersionPair, Task <PackageDetails> >(); if (!actionsOnly) { var sourceFileToInvocations = new[] { SourceFileToCodeTokens(sourceFileResult) }.ToDictionary(result => result.Key, result => result.Value); sourceFileToCodeEntityDetails = CodeEntityModelToCodeEntities.Convert(sourceFileToInvocations, externalReferences); var namespaces = sourceFileToCodeEntityDetails.Aggregate(new HashSet <string>(), (agg, cur) => { agg.UnionWith(cur.Value.Select(i => i.Namespace).Where(i => i != null)); return(agg); }); var nugetPackages = externalReferences?.NugetReferences? .Select(r => CodeEntityModelToCodeEntities.ReferenceToPackageVersionPair(r))? .ToHashSet(); var subDependencies = externalReferences?.NugetDependencies? .Select(r => CodeEntityModelToCodeEntities.ReferenceToPackageVersionPair(r)) .ToHashSet(); var sdkPackages = namespaces.Select(n => new PackageVersionPair { PackageId = n, Version = "0.0.0", PackageSourceType = PackageSourceType.SDK }); var allPackages = nugetPackages .Union(subDependencies) .Union(sdkPackages) .ToList(); packageResults = _handler.GetNugetPackages(allPackages, solutionFilePath, isIncremental: true, incrementalRefresh: false); recommendationResults = _recommendationHandler.GetApiRecommendation(namespaces.ToList()); } var portingActionResults = new Dictionary <string, List <RecommendedAction> >(); var recommendedActions = fileActions.Select(f => new RecommendedAction() { Description = f.Description, RecommendedActionType = RecommendedActionType.ReplaceApi, TextSpan = new Model.TextSpan() { StartCharPosition = f.TextSpan.StartCharPosition, EndCharPosition = f.TextSpan.EndCharPosition, StartLinePosition = f.TextSpan.StartLinePosition, EndLinePosition = f.TextSpan.EndLinePosition }, TextChanges = f.TextChanges }).ToHashSet().ToList(); portingActionResults.Add(filePath, recommendedActions); var sourceFileAnalysisResult = CodeEntityModelToCodeEntities.AnalyzeResults( sourceFileToCodeEntityDetails, packageResults, recommendationResults, portingActionResults, targetFramework, compatibleOnly); //In case actions only, result will be empty, so we populate with actions if (actionsOnly) { sourceFileAnalysisResult.Add(new SourceFileAnalysisResult() { SourceFileName = Path.GetFileName(filePath), SourceFilePath = filePath, RecommendedActions = recommendedActions, ApiAnalysisResults = new List <ApiAnalysisResult>() }); } sourceFileAnalysisResults.AddRange(sourceFileAnalysisResult); return(sourceFileAnalysisResults); } finally { CommonUtils.RunGarbageCollection(_logger, "PortingAssistantAnalysisHandler.AnalyzeFileIncremental"); } }
private ProjectAnalysisResult AnalyzeProject( string project, string solutionFileName, List <AnalyzerResult> analyzers, List <ProjectResult> analysisActions, bool isIncremental = false, string targetFramework = DEFAULT_TARGET) { try { var analyzer = analyzers.Find((a) => a.ProjectResult?.ProjectFilePath != null && a.ProjectResult.ProjectFilePath.Equals(project)); var projectFeatureType = analysisActions.Find((a) => a.ProjectFile != null && a.ProjectFile.Equals(project))?.FeatureType.ToString(); var projectActions = analysisActions.FirstOrDefault(p => p.ProjectFile == project)?.ProjectActions ?? new ProjectActions(); if (analyzer == null || analyzer.ProjectResult == null) { _logger.LogError("Unable to build {0}.", project); return(null); } var sourceFileToCodeTokens = analyzer.ProjectResult.SourceFileResults.Select((sourceFile) => { return(SourceFileToCodeTokens(sourceFile)); }).ToDictionary(p => p.Key, p => p.Value); var sourceFileToCodeEntityDetails = CodeEntityModelToCodeEntities.Convert(sourceFileToCodeTokens, analyzer); var namespaces = sourceFileToCodeEntityDetails.Aggregate(new HashSet <string>(), (agg, cur) => { agg.UnionWith(cur.Value.Select(i => i.Namespace).Where(i => i != null)); return(agg); }); var targetframeworks = analyzer.ProjectResult.TargetFrameworks.Count == 0 ? new List <string> { analyzer.ProjectResult.TargetFramework } : analyzer.ProjectResult.TargetFrameworks; var nugetPackages = analyzer.ProjectResult.ExternalReferences.NugetReferences .Select(r => CodeEntityModelToCodeEntities.ReferenceToPackageVersionPair(r)) .ToHashSet(); var nugetPackageNameLookup = nugetPackages.Select(package => package.PackageId).ToHashSet(); var subDependencies = analyzer.ProjectResult.ExternalReferences.NugetDependencies .Select(r => CodeEntityModelToCodeEntities.ReferenceToPackageVersionPair(r)) .ToHashSet(); var sdkPackages = namespaces.Select(n => new PackageVersionPair { PackageId = n, Version = "0.0.0", PackageSourceType = PackageSourceType.SDK }).Where(pair => !nugetPackageNameLookup.Contains(pair.PackageId)); var allPackages = nugetPackages .Union(subDependencies) .Union(sdkPackages) .ToList(); Dictionary <PackageVersionPair, Task <PackageDetails> > packageResults; if (isIncremental) { packageResults = _handler.GetNugetPackages(allPackages, solutionFileName, isIncremental: true, incrementalRefresh: true); } else { packageResults = _handler.GetNugetPackages(allPackages, null, isIncremental: false, incrementalRefresh: false); } var recommendationResults = _recommendationHandler.GetApiRecommendation(namespaces.ToList()); var packageAnalysisResults = nugetPackages.Select(package => { var result = PackageCompatibility.IsCompatibleAsync(packageResults.GetValueOrDefault(package, null), package, _logger, targetFramework); var packageAnalysisResult = PackageCompatibility.GetPackageAnalysisResult(result, package, targetFramework); return(new Tuple <PackageVersionPair, Task <PackageAnalysisResult> >(package, packageAnalysisResult)); }).ToDictionary(t => t.Item1, t => t.Item2); var portingActionResults = ProjectActionsToRecommendedActions.Convert(projectActions); var SourceFileAnalysisResults = CodeEntityModelToCodeEntities.AnalyzeResults( sourceFileToCodeEntityDetails, packageResults, recommendationResults, portingActionResults, targetFramework); var compatibilityResults = GenerateCompatibilityResults(SourceFileAnalysisResults, analyzer.ProjectResult.ProjectFilePath, analyzer.ProjectBuildResult?.PrePortCompilation != null); return(new ProjectAnalysisResult { ProjectName = analyzer.ProjectResult.ProjectName, ProjectFilePath = analyzer.ProjectResult.ProjectFilePath, TargetFrameworks = targetframeworks, PackageReferences = nugetPackages.ToList(), ProjectReferences = analyzer.ProjectResult.ExternalReferences.ProjectReferences.ConvertAll(p => new ProjectReference { ReferencePath = p.AssemblyLocation }), PackageAnalysisResults = packageAnalysisResults, IsBuildFailed = analyzer.ProjectResult.IsBuildFailed() || analyzer.ProjectBuildResult.IsSyntaxAnalysis, Errors = analyzer.ProjectResult.BuildErrors, ProjectGuid = analyzer.ProjectResult.ProjectGuid, ProjectType = analyzer.ProjectResult.ProjectType, FeatureType = projectFeatureType, SourceFileAnalysisResults = SourceFileAnalysisResults, MetaReferences = analyzer.ProjectBuildResult.Project.MetadataReferences.Select(m => m.Display).ToList(), PreportMetaReferences = analyzer.ProjectBuildResult.PreportReferences, ProjectRules = projectActions.ProjectRules, ExternalReferences = analyzer.ProjectResult.ExternalReferences, ProjectCompatibilityResult = compatibilityResults }); } catch (Exception ex) { _logger.LogError("Error while analyzing {0}, {1}", project, ex); return(new ProjectAnalysisResult { ProjectName = Path.GetFileNameWithoutExtension(project), ProjectFilePath = project, TargetFrameworks = new List <string>(), PackageReferences = new List <PackageVersionPair>(), ProjectReferences = new List <ProjectReference>(), PackageAnalysisResults = new Dictionary <PackageVersionPair, Task <PackageAnalysisResult> >(), IsBuildFailed = true, Errors = new List <string> { string.Format("Error while analyzing {0}, {1}", project, ex) }, ProjectGuid = null, ProjectType = null, SourceFileAnalysisResults = new List <SourceFileAnalysisResult>() }); } finally { CommonUtils.RunGarbageCollection(_logger, "PortingAssistantAnalysisHandler.AnalyzeProject"); } }